webForumDet fria alternativet

Tabellstruktur sql tillägg

17 svar · 898 visningar · startad av überfuzz

überfuzzMedlem sedan apr. 2006409 inlägg
#1

Jag har en tabell med statistik över köp. Några varor kommer att ha tilllägg och några kommer inte att ha det. I tabellen har jag en kolumn för produkt som mha ett index pekar ut rätt vara i en tabell[produkt]. Nu måste jag komma på ett bra sätt att få in tilläggen. Förklaringen blir, milt sagt, rörig så jag försöker förklara med ett exempel.

köp
id | referens_nr | produkt_id | tid

produkt
produkt_id | produkt

Om vi har tabellerna ovan och det görs ett köp av en cykel med tillbehören stödhjul och cykelljus. Hur sparar man stödhjul och cykelljus på bästa sätt? Min idé är/var att ha kolumner i köp-tabellen som är tomma till ett tillägg förs in. Men det känns lite dumt att ha tre/fyra kolumner som till mestadels står tomma..?

Peter SMedlem sedan dec. 20025 483 inlägg
#2

Upprätta en många-till-många-tabell:

köp_tillägg
-------------------
köp-id | tillägg-id
-------------------
   1   |     1    |
-------------------
   1   |     3    |
-------------------
   4   |     7    |
-------------------

Primärnyckel är de båda id:na.

Fredde MannenMedlem sedan nov. 20014 054 inlägg
#3

Ha en tabell som heter typ "tillägg", "tillbehör", denna funkar som en kopplingstabell som har

produkt_id och tillbehor_id

Sen för att se om produkten har några tillbehör, kollar du i tillhörstabellen om produkt_id finns i produkt_id och hämtar alla tillbehor_id som är kopplade till det produkt_id (i tabellen tillbehor är tillbehor_id (en annan produkt i produkt-tabellen))

Eller om du då istället har köpets id i tillbehor och produktid som motsvarar tillbehoret för köpet.

Kan ju vara en lösning. :)

Fredde MannenMedlem sedan nov. 20014 054 inlägg
#4

Attans.. också.. Peter han före..

überfuzzMedlem sedan apr. 2006409 inlägg
#5

Oj, tack för blixtsnabba svar.

Jag är rätt grön på sql/tabellstruktur. Det är några saker jag inte riktigt fattar.

Peter S skrev:

köp_tillägg
-------------------
köp-id | tillägg-id
-------------------
1 | 1 |
-------------------
1 | 3 |
-------------------
4 | 7 |
-------------------
Primärnyckel är de båda id:na.

För att se om jag förstått det du skrev. I ditt exempel har köp 1 tillägg 1 och tillägg 3, vidare köp 4 tillägg 7. Låt säga att jag har strängar som beskriver tilläggen och vill byta index:en till strängar när jag query:ar ut raderna? Menar du att tillägg_id pekar på en tabell där ett auto_increment-index pekar på en sträng? Vidare hur hämtar jag ut köprader så att jag får med tilläggen?

Peter SMedlem sedan dec. 20025 483 inlägg
#6

Japp, precis så. Du joinar alltså tabellen köp_tillägg med tilläggstabellen på dess id.

Säg att du vill hämta ut ett köp med id = 4:

select * from köp k left join köp_tillägg t on k.id = t.köp-id
left join tillägg g on t.tillägg-id = g.id
where k.id = 4;

...i stället för * kan (och bör) du ange vilka fältnamn från respektive tabell du vill ha ut, kvalificerade med tabellalias (t.ex. g.Tilläggsnamn).

überfuzzMedlem sedan apr. 2006409 inlägg
#7

Puhh, nu blev det mycket nytt för mig...

Okej, jag hämtar köp 1 med din query. Hur kommer raderna då?

Med left join-tricket:
1 | cykel | cykelljus
1 | cykel | stödhjul

Eller blir det så här?

1 | cykel | t | g
(Där g och t är enligt din namngivning, förslagsvis)
1 | cykel | cykelljus | stödhjul

Peter SMedlem sedan dec. 20025 483 inlägg
#8

Enligt det första alternativet. Finns inga tillägg kommer i stället NULL att stå där.

überfuzzMedlem sedan apr. 2006409 inlägg
#9

Tusen tack!

Nu måste jag rota i det ett tag.

überfuzzMedlem sedan apr. 2006409 inlägg
#10

Nu dök det upp en fråga till. JOIN LEFT
I mitt fall har jag även tabellerna result r och product p och inom kort extra e & result_extra r_e Men först, jag förstår inte grejerna med JOIN LEFT som du gjort.

Jag har försökt förstå och skrivit kommentarer, hur jag tror att det fungerar.

FROM result r, product p
LEFT JOIN	result_extra r_e ON r.id = r_e.result-id
//Om tabellen result_extra har en nyckel[id] som passar med result[id] hämtas den. (Ska det vara bindesträck på r_e.result-id?)
LEFT JOIN	extra e ON r_e.extra-id = e.id
//Om result_extra har hämtats omvandlas den till sträng mha tabellen extra.

Tabellerna:
result
id | product_id | time | etc

result_extra
id | extra_id --- id är primärnyckeln för result och extra_id är tilläggets index.

extra
extra_id | extra --- index extra_id pekar på strängen tillägg.

Peter SMedlem sedan dec. 20025 483 inlägg
#11

Anledningen till att LEFT JOIN använts och inte INNER JOIN, är att alla köp kanske inte har något tillägg. Hade INNER använts skulle sådana köp inte plockats ut. Men med LEFT får vi alla rader i den vänstra tabellen, även om det inte finns någon matchning i den högra (i dessa fall får vi NULL).

Bindestreck skall sannolikt inte användas. I ditt fall är ju result-id ett kolumnnamn i databasen och den stavningen skall reflekteras i SQL-frågorna. I manualen för din databashanterare bör det framgå vilka tecken som är tillåtna i kolumnnamn.

Finns det alltid ett samband mellan result och product kan du använda en INNER JOIN mellan dem:

from ((result r
inner join product p on ...)
left join result_extra r_e on ...)
left join extra e on ...
überfuzzMedlem sedan apr. 2006409 inlägg
#12

Hej, igen.

Jag satt och pillade med left join och försökte få till en lättbegriplig presentation. Vet inte om det är mina sql-querys som sätter gränser eller om jag kanske borde tänka om. Först och främst vet jag inte riktigt hur jag strukturerar hämtningen/presentationen på det mest begripliga sättet.

Ett exempel: En kund köper 3 cyklar och en stol, en av cyklarna har stödhjul som tillägg.

Vara
produkt | antal | pris | kostnad
cykel | 3 | 1500 | 3500
stol | 1 | 299 | 299

Tillägg
produkt | antal | pris
cykelstöd | 1 | 79

Tidigare försökte jag få in allt i en och samma tabell, utan att få till det. Nu funderar jag på att köra som i exemplet här ovanför i stället.
FRÅGA: Finns det något tjusigt lättbegripligt sätt att presentera köpet med tillägg i en och samma tabell?

Peter SMedlem sedan dec. 20025 483 inlägg
#13

Teoretiskt kan du ju ha en enda massiv tabell med all information sparad; i början kanske du har två tilläggsfält, men efter tid märker du att oj, nu finns det visst en vara som har 718 tillägg och lägger därför till ytterligare 716 fält. Nu, för de flesta varor kommer drygt 700 av dessa fält alltid att innehålla NULL, så egentligen är det ju slöseri med utrymme att göra på det viset.

Den långsiktiga lösningen är självklart att normalisera tabellstrukturen och göra som i exemplet ovanför.

überfuzzMedlem sedan apr. 2006409 inlägg
#14

Ja, själva tabellstrukturen tror jag fungerar som den är nu. Mitt problem är nog snarare att jag inte behärskar sql syntaxen speciellt bra. Jag kan ju visa hur jag hämtar info nu.

Hämtning av tillägg - extra

SELECT extra.*
FROM result
INNER JOIN result_extra
ON result.id = result_extra.result_id
LEFT JOIN extra
ON result_extra.result_id = extra.extra_id

Här får jag tomma kolumner (det finns tre matchade: result - result_extra där alla kolumner i extra har värden).
Array
(
[0] =>
[extra_id] =>
[1] =>
[client] =>
[2] =>
[extra] =>
[3] =>
[extra_pay] =>
)

extra_id:

Array
(
[0] =>
[extra_id] =>
[1] =>
[client] =>
[2] =>
[extra] =>
[3] =>
[extra_pay] =>
)

extra_id:

Array
(
[0] =>
[extra_id] =>
[1] =>
[client] =>
[2] =>
[extra] =>
[3] =>
[extra_pay] =>
)

Vidare hämtar jag ur result så här:

SELECT 	pay,
	client,
	product,
	SUM(pay) AS tot_pay,
	COUNT(product) AS count_product

FROM	product p,
	result r

WHERE	r.product_id = p.product_id
	AND control = 1
	AND waste_id IS NULL

GROUP BY product
ORDER BY client

Och det får jag ut som jag vill. Frågan var väl luddig antar jag, jag försöker igen. Är det bättre att lägga ihop de två query:na till en och presentera det i en tabell, eller är det kanske smartare att ha två query:s och presentera info:n i två tabeller?

Peter SMedlem sedan dec. 20025 483 inlägg
#15

Om du vill hämta allt som finns i result, även om det inte finns något i extra kopplat till en sådan post, får du byta INNER mot LEFT.

Vill du presentera resultat-, produkt- och extrainformation tillsammans, skulle i alla fall jag försöka slå ihop SQL-frågorna till en enda. Är det separata tabeller i presentationen kanske jag skulle överväga att även använda separata SQL-frågor.

überfuzzMedlem sedan apr. 2006409 inlägg
#16

Ja, jag vet inte. Det får jag nog bestämma när jag lyckats testat båda alternativen.

Följande tar ut alla rader där result_ID = ID och allt är frid och fröjd.

SELECT		result_extra.result_id, result_extra.extra_id

FROM 		result_extra
INNER JOIN 	result
ON 		result_extra.result_ID = result.ID

Ger:
Array
(
[result_ID] => 5
[extra_id] => 1
)

Array
(
[result_ID] => 5
[extra_id] => 2
)

Array
(
[result_ID] => 8
[extra_id] => 2
)

När jag lägger till en join för att koppla extra_id till tabellen extra, blir det fel. Det kommer bara med en av varje extra_id, eller tillägg.

SELECT		extra.extra, extra.extra_pay

FROM 		result_extra
INNER JOIN 	result
ON 		result_extra.result_ID = result.ID

RIGHT JOIN 	extra
ON 		result_extra.extra_id = extra

Array
(
[extra] => Tillägg1
[extra_pay] => 50
)

Array
(
[extra] => Tillägg2
[extra_pay] => 30
)

Vad gör jag för fel när jag försöker koppla ihop result_extra med extra?

Peter SMedlem sedan dec. 20025 483 inlägg
#17
SELECT		extra.extra, extra.extra_pay

FROM 		result
LEFT JOIN 	result_extra
ON 		result_extra.result_ID = result.ID

LEFT JOIN 	extra
ON 		result_extra.extra_id = extra
überfuzzMedlem sedan apr. 2006409 inlägg
#18

T-t-t, jag hade slarvat med några grejer. Jag gick igenom mina koder och tabeller, det var några fel som jag rättade till. Nu fungerar sql-query:n med inner join.

Nu tänkte jag testa och se hur det ser ut med tilläggen presenterade i en separat tabell. Efter det gör jag en med allt i ett som du föreslog och ser om jag kan få till det bättre med ditt förslag på query.

141 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
138 ms — hämta tråd, inlägg och bilagor (db)