För det första så är det inget som säger att det finns ett unikt svar. Detta kom jag fram till levererar ett svar om datumspannet inte går i varandra. Ja, det är ju samma som jag skrev, förutom att du hanterar ett null-fall och bara väljer ett svar. Frågan är om du vill välja ett enda svar helt random på det sättet... Men vad vill du få ut om du har följande? Det jag vill är att ha en standard frukt per person men frukten kan bytas mellan vissa datum. Dock skall det inte gå att mata in datuomfång så det blir mer svar än två så att TOP 1 fungerar som jag tänkt. För det första gör du ingen join, för det andra döper du inte om kolumnen utan hela delfrågan. Något följande bör funka bättre (helt otestat dock): Något att bita i. Men får min access databas att paja med den SQL-frågan. Gör en liten fråga först, bygg på den i delar. Det jag menar är: På detta sätt sorteras också frukterna med sollning av alla övriga avikelser från tabellen "mellis" som ligger utanför datumomfånget. Men dubbelposter erhålles iallafall ... suck Nu börjar denna tråd bli tjock... men det verkar vara omöjligt att få till det så som jag önskar. Ok, nu hinner jag inte läsa igenom det du tidigare, men nyckelordet här verkar vara "mest aktuella"? JIPPI!!! No probs. Tänk alltid i små steg; vad har jag, vad behöver jag, vad måste jag då lägga till? Utan min / max på datumet så tror jag det hade varit omöjligt att nå en rimlig lösning.SQL nöt
Jag har en tabell som se ut som nedan.
Det jag önskar att med en SQLfråga få en rapport om vad som gäller för en veckodag
om veckodag=MÅNDAG och dagensdatum är 2007-12-12 skall fruktsvaret bli: banan
om veckodag=MÅNDAG och dagensdatum är 2008-01-10 skall fruktsvaret bli: äpple
om veckodag=MÅNDAG och dagensdatum är 2008-11-10 skall fruktsvaret bli: banan
om veckodag=TISDAG och dagensdatum är 2007-12-12 skall fruktsvaret bli: banan
om veckodag=TISDAG och dagensdatum är 2008-01-10 skall fruktsvaret bli: banan
Någon som vet hur man skriver SQL frågan?
<code>
nr veckodag frdat tidat frukt
=========================================
1 MÅNDAG 2007-01-01 banan
2 MÅNDAG 2008-01-01 2008-10-10 äpple
3 TISDAG 2007-01-01 banan
</code>Sv: SQL nöt
För det andra är "Veckodag" som sträng en tämligen märklig konvention.
Oavsett:
SELECT frukt FROM Tabell WHERE ((frdat < today) AND (tidat > today)) AND veckodag = idag Sv:SQL nöt
<code>
SELECT top 1 frukt
FROM tabell
WHERE ((frdat < #2008-01-10# and tidat is null) or (frdat < #2008-01-10# and tidat > #2008-01-10#)) and veckodag='måndag'
ORDER BY tidat desc ;
</code>
Går det att optimera ?Sv: SQL nöt
Har svårt att se att det skulle gå att optimera om du pratar om prestanda.
En lämplig ändring hade nog varit att ta bort tidat helt och hållet, saker gäller tills nästa grej börjar gälla. Och sen skulle jag rekommendera ett omtänk vad gäller "veckodag".Sv:SQL nöt
Ok det jag slutlig önskar en lösning på är att slå samman dessa två tabeller som visas nedan :
Personer
<code>
nr namn
===================
1 Olle
2 Nisse
</code>
Mellis
<code>
nr person frdat tidat frukt
===================================
1 1 2007-01-01 banan
2 1 2008-01-01 2008-10-10 äpple
2 2 2007-01-01 banan
</code>
Vill få nedan svar i en fråga om dagens datum är 2008-01-10
<code>
namn frukt
===================
Nisse banan
Olle äpple
</code>
Nedan SQL-fråga fungerar förutom att jag önskar sortera i stigande för kolumnen _frukt. Hur skall man lösa den nöten ?
<code>
SELECT
personer.person,
(SELECT top 1 mellis.frukt
FROM mellis
WHERE ((mellis.frdat < #2008-01-10# and mellis.tidat is null) or (mellis.frdat < #2008-01-10# and mellis.tidat > #2008-01-10#)) and mellis.person = personer.nr
ORDER BY mellis.tidat desc ;) as _frukt
FROM personer
ORDER BY personer.person;
</code>Sv: SQL nöt
<code>
nr person frdat tidat frukt
===================================
1 1 2007-01-01 banan
2 1 2008-01-01 2008-10-10 äpple
3 1 2008-01-02 2008-10-05 apelsin
4 2 2007-01-01 banan
</code>
Och dagens datum är 2008-01-03?
Det rimligaste är:
<code>
namn frukt
===================
Nisse banan
Nisse apelsin
Olle äpple
</code>
Du saknar alltså information för att avgöra vilken av dem du ska välja.
I övrigt så är det bara att ta den queryn du har och joina med namnen?
<b>>Kan inte köra en (select top 1...) as _frukt för kolumn frukt pga jag vill sortera i stigande på den kolumnen. </b>
Öh... varför skulle inte det gå?Sv:SQL nöt
I nedan SQLfråga blir det fel på ORDER BY pga _frukt ... vad är lösningen?
<code>
SELECT
personer.person,
(SELECT top 1 mellis.frukt
FROM mellis
WHERE ((mellis.frdat < #2008-01-10# and mellis.tidat is null) or (mellis.frdat < #2008-01-10# and mellis.tidat > #2008-01-10#)) and mellis.person = personer.nr
ORDER BY mellis.tidat desc ;) as _frukt
FROM personer
ORDER BY personer.person, _frukt;
</code>
Den join fråga jag försökt med levererar svar på allt. Vet inte hur jag skulle kunna klämma in en "TOP 1" i en join lösning..?Sv: SQL nöt
<code>
SELECT
personer.person FROM personer
INNER JOIN
(SELECT top 1 mellis.frukt as _frukt
FROM mellis
WHERE ((mellis.frdat < #2008-01-10# and mellis.tidat is null) or (mellis.frdat < #2008-01-10# and mellis.tidat > #2008-01-10#))
ORDER BY mellis.tidat desc) AS fruktval
ON and fruktval.person = personer.nr
ORDER BY personer.person, fruktval._frukt;
</code>
Det är möjligt att din hembakade join skulle funka.Sv:SQL nöt
Vad kan vara galet? Är mycket nyfiken!
Den jion ...jag labbat med är :
<code>
SELECT personer.person, mellis.frukt
FROM personer INNER JOIN mellis ON personer.nr = mellis.person
WHERE (((mellis.tidat) Is Null) AND ((mellis.frdat)<#1/10/2008#)) OR (((mellis.tidat)>#1/10/2008#) AND ((mellis.frdat)<#1/10/2008#))
ORDER BY mellis.tidat DESC;
</code>Sv: SQL nöt
SELECT personer.person, mellis.frukt
FROM personer INNER JOIN mellis ON personer.nr = mellis.person
Funkar det?
Ta ut alla kolumnerna som är intressanta, lägg hela ovanstående query inom parenteser, och gör en ny query på den, så bör du kunna ordna det rätt lätt.
Sv:SQL nöt
Du får ursäkta men jag fattar inte riktigt vad du menar med detta :
"Ta ut alla kolumnerna som är intressanta, lägg hela ovanstående query inom parenteser, och gör en ny query på den, så bör du kunna ordna det rätt lätt."
Dessvärre är jag redan flintig hade jag inte varit det så hade jag blivit det. :-) Sv: SQL nöt
1. Skriv följande fråga och spara den:
SELECT *
FROM personer INNER JOIN mellis ON personer.nr = mellis.person
2. Kolla att den funkar, den ska bara plocka ut alla korrekta kombinationer.
3. Lägg till alla kolumner som du behöver (jag föredrar att ange alla kolumner istället för *):
SELECT personer.person, mellis.frukt, mellis.frdat, ...
FROM personer INNER JOIN mellis ON personer.nr = mellis.person
4. Ändra frågan till:
SELECT * FROM
(SELECT personer.person, mellis.frukt, mellis.frdat, ...
FROM personer INNER JOIN mellis ON personer.nr = mellis.person)
5. Redigera det som står före och efter för att göra det valet du behöver. Gör det i små steg så att allt blir lätt, slutprodukten blir nog något i stil med:
SELECT personer.person, mellis.frukt FROM
(SELECT personer.person, mellis.frukt, mellis.frdat, ...
FROM personer INNER JOIN mellis ON personer.nr = mellis.person)
WHERE frdat<idag, ....
ORDER BY frukt
Du kan alltså betrakta allt inom () som en enda tabell, rör inte den mer när du har fått till den rätt.Sv:SQL nöt
Menar du så här ?
<code>
SELECT personer.person, mellis.frukt FROM
(SELECT * FROM personer INNER JOIN mellis ON personer.nr = mellis.person )
WHERE ((mellis.frdat < #2008-01-10# and mellis.tidat is null) or (mellis.frdat < #2008-01-10# and mellis.tidat > #2008-01-10#)) and mellis.person = personer.nr
ORDER BY mellis.tidat desc ;
</code>
Men den svaret blir dubbelpost för OlleSv:SQL nöt
1. Jag har min personer tabell som jag vill lopa igenom. Jag vill komplettera min personer tabell med en extra kollumn som heter frukt.
2. När jag står på första posten i tabellen personer med nr 1 så vill jag plocka den mest aktuella matchande posten i tabellen "mellis" där kolumnen frukt ingår. Det finns alltid en post som matchar personer.nr=mellis.person med endast ett "startdatum" angivet för kolumnen "frdat". När det erhålles två poster så har en avvikelse noterats mellan två datum (från och till) där "standard" frukten "banan" för person nr1 skall bytas mot "äpple".
Om dagens datum är innanför de två datumen (från och till) skall den postens värde för kolumnen frukt anslutas till tabellen personer. Om dagens datum inte ligger innanför de två datumen skall den post med bara "start" datum anlutas.
osv ...
för att kunna leverera endast ett svar känner jag bara till lösninegn att först sortera bort alla poster som ligger utanför dagensdatum och sedan vända sorterings ordningen och plocka ut första posten med kommandot "Top 1".
hur jag än vänder och vrider så får jag bara möjligenheten att leverera rätt svar som jag kan ansluta till min huvudtabell utan att kunna köra sortering på min nya kolumn. Eller så lägger jag till min kolumn genom en Inner Join och kan utöva sortering men erhåller då alla eventuella dubbelposter.
olycklig!Sv: SQL nöt
<code>
SELECT personer.nr, personer.person, xmellis.fruktis
FROM personer
INNER JOIN (SELECT (mellis.frukt) as fruktis, (mellis.person) as xperson FROM mellis WHERE ((mellis.frdat < #2008-01-10# and mellis.tidat is null) or (mellis.frdat < #2008-01-10# and mellis.tidat > #2008-01-10#)) ORDER BY mellis.tidat desc ) as xmellis ON personer.nr = xmellis.xperson
ORDER BY personer.person, xmellis.fruktis
</code>Sv:SQL nöt
Kanske går det om man kan skriva en where sats utan att tvings använda "TOP" skulle det fungera
<code>
nr namn frdat tidat
============================
1 olle 2007-01-01
2 olle 2008-01-01 2008-10-10
</code>
Finns det en möjlighet via en WHERE-sats att plocka post nr2 med dagens datum och post nr om dagens datum är 2008-10-11 ?Sv:SQL nöt
Det är alltså den som är aktuell, och som har senaste startdatum?
Då är det det du ska arbeta med först.
1. Välj ut alla som är aktuella:
SELECT * FROM mellis WHERE ((mellis.frdat < #2008-01-10# and mellis.tidat is null) or (mellis.frdat < #2008-01-10# and mellis.tidat > #2008-01-10#))
2. För varje person, välj ut den med senast från-datum.
SELECT min(frdat) FROM mellis WHERE ((frdat < #2008-01-10# and tidat is null) or (frdat < #2008-01-10# and tidat > #2008-01-10#)) GROUP BY person
3. Välj ut de enskilda posterna
SELECT * FROM mellis RIGHT JOIN
(SELECT person, min(frdat) FROM mellis WHERE ((frdat < #2008-01-10# and tidat is null) or (frdat < #2008-01-10# and tidat > #2008-01-10#)) GROUP BY person) AS Active
ON mellis.frdat = Active.frdat AND mellis.person = Active.person
4. Joina sen ihop detta för att få fram personnamnet också.Sv: SQL nöt
1. Denna fråga tar fram en tabell för de "frdat" datum jag söker efter person
<code>
SELECT person, max(frdat) as _frdat FROM mellis WHERE ((frdat < #2008-01-10# and tidat is null) or (frdat < #2008-01-10# and tidat > #2008-01-10#)) GROUP BY person
</code>
2. Jag tar tabellen från punkt 1 ovan och döper den till datum. Jag får fram de datum till personer jag söker efter.
<code>
SELECT * from (SELECT person, max(frdat) as _frdat FROM mellis WHERE ((frdat < #2008-01-10# and tidat is null) or (frdat < #2008-01-10# and tidat > #2008-01-10#)) GROUP BY person) as datum
</code>
3. Jag JOIN:ar tabellen mellis för att länka samman den med min nya tabell "datum".
<code>
SELECT * from (SELECT person, max(frdat) as _frdat FROM mellis WHERE ((frdat < #2008-01-10# and tidat is null) or (frdat < #2008-01-10# and tidat > #2008-01-10#)) GROUP BY person) as datum
INNER JOIN mellis on mellis.frdat = datum._frdat and mellis.person = datum.person
</code>
4. Men det blir fel .... access gnäller över att "mellis.frdat = datum._frdat" är felaktig ???Sv:SQL nöt
FELET I DENNA FRÅGA ÄR "_frdat"!
<code>
SELECT * from (SELECT person, max(frdat) as _frdat FROM mellis WHERE ((frdat < #2008-01-10# and tidat is null) or (frdat < #2008-01-10# and tidat > #2008-01-10#)) GROUP BY person) as datum
INNER JOIN mellis on mellis.frdat = datum._frdat and mellis.person = datum.person
</code>
KORREKT FUNGERADE ÄR FÖLJANDE :
<code>
SELECT * from (SELECT person, max(frdat) as xfrdat FROM mellis WHERE ((frdat < #2008-01-10# and tidat is null) or (frdat < #2008-01-10# and tidat > #2008-01-10#)) GROUP BY person) as datum
INNER JOIN mellis on mellis.frdat = datum.xfrdat and mellis.person = datum.person
</code>Sv:SQL nöt
Sv: SQL nöt
Ibland kommer man bara inte på alla olika möjligheter som erbjuds i ett språk.
/Magnus