webForumDet fria alternativet

Smart select query (advancerad)

5 svar · 657 visningar · startad av Simkisen

SimkisenMedlem sedan jan. 200358 inlägg
#1

Tja,
tänkte se om det finns några smarta killar/tjejer här och fråga om hjälp med en query som jag försöker åstadkomma. Denna query ska hämta ut en mängd rader men ibland kan det finnas 2 rader som har samma värde på alla fält utom två och då skall den välja rätt rad mellan dom två raderna.

Lite databas exempel..förenklat
-------------------------------------
id | type | price | some_id
-------------------------------------
1 | SHOE | 100 | null
2 | SHOE | 90 | 1
3 | SHOE | 95 | 2
4 | SHIRT | 150 | null
-------------------------------------

man vet some_id och vill hämta ut raderna för dom, med LEFT JOIN så får man alla rader man vill ha plus några extra.
då får man t.ex ut dessa ifall man har some_id = 1
---------------------
1 | SHOE | 100 | null
2 | SHOE | 90 | 1
4 | SHIRT | 150 | null
---------------------

men istället skulle jag vilja få ut dessa
----------------------
2 | SHOE | 90 | 1
4 | SHIRT | 150 | null
----------------------

man skulle kunna köra group by på type, men tyvärr fungerar det inte med entiteter i Java då detta egentligen skall göras med JPQL, dock någon av att göra detta med en vanlig SQL query så kan jag troligen översätta det till JPQL.

funderade på om det skulle gå o göra en IF i queryn och kolla ifall man hittar flera utav en type och isf på något vis hämta ut rätt, men har inte kommit på något vettigt sätt att lösa det på.

Ett alternativ är att göra flera querys men skulle helst lösa det med en enda.

Några idéer?

(p.s förlåt att jag inte kom på en vettigare rubrik)

EDIT: MySQL5 databas med Toplink Essentials som JPA lösning.

SimkisenMedlem sedan jan. 200358 inlägg
#2

hmm, löste det med ett massa sub-querys

SELECT e 
FROM Entity e 
WHERE 
  e.id IN 
  (
    SELECT e2.id 
    FROM Entity e2 
    WHERE 
      e2.some_id = :some_id
  ) 
  AND e.type NOT IN 
  (
    SELECT e3.type 
    FROM Entity e3 
    WHERE 
      e3.some_id = :some_id
  )

observera att båda sub-querys gör exakt samma sak förutom att dom tar ut olika fält, om det skulle gå att slå ihop den funktionaliteten så man bara gör en subquery vore nice, men vet inte om det går, någon som vet?

nitro2k01Medlem sedan aug. 20037 630 inlägg
#3

Om jag inte är alltför morgontrött bör något sådant här funka. Tricket ligger i e3.type IS NULL.

SELECT e.* 
FROM Entity e 
LEFT JOIN Entity e2
  ON e.id = e2.id
LEFT JOIN Entity e3
  ON e.type = e3.type
WHERE 
  e2.some_id = :some_id
  AND e3.some_id = :some_id
  AND e3.type IS NULL
SimkisenMedlem sedan jan. 200358 inlägg
#4

type kan inte vara null, endast some_id kan vara det. e, e2, e3 är alla samma tabell/entitet men det jag gjorde tar ut olika samlingar och lägger ihop dom.
id är primary keyn, uppdaterade exemplen för att reflektera det.

kanske missade säga en sak men med t.ex some_id = 1 ska man ju få ut
----------------------
2 | SHOE | 90 | 1
4 | SHIRT | 150 | null
----------------------

men med samma data som jag skrev i första posten och some_id = 3 (finns inget med id 3) så ska jag få ut följande
----------------------
1 | SHOE | 100 | null
4 | SHIRT | 150 | null
----------------------

nitro2k01Medlem sedan aug. 20037 630 inlägg
#5

Simkisen skrev:

type kan inte vara null

Spelar ingen roll. IS NULL används i detta fall för att exkludera rader där e.type = e3.type är sant. Om matchningen går åt pipan så finns det inget att lägga i e3.type som då blir null. Raden godkänns då. Den konstruktionen är till för att ersätta

e.type NOT IN 
  (
    SELECT e3.type 
    FROM Entity e3 
    WHERE 
      e3.some_id = :some_id
  )
SimkisenMedlem sedan jan. 200358 inlägg
#6

går inge vidare med o joina som du gjort med JPQL den envisas med att det jag joinat ger en lista på integers eller strängar så har inte tillgång till själva entiten och kan inte göra dom jämförelserna som behövs i WHERE satsen.

invalid navigation expression [e2.some_id], cannot navigate expression [e2] of type [java.lang.Integer] inside a query.

dör på första where satsen och antar att det samma skulle gälla för de andra.

Genererad på 379 ms · cache AV · v20260730165559-full.f96bc7eb