---
title: "Mysql join 2 ggr på samma tabell (wordpress)"
type: "forum-thread"
url: "https://www.webforum.nu/amne/databaser-sql/188457-mysql-join-2-ggr-på-samma-tabell-wordpress"
topic: "Databaser & SQL"
topic_url: "https://www.webforum.nu/amne/databaser-sql"
author: "niska"
published: "2011-11-21T20:38:36.000Z"
updated: "2011-11-23T10:40:17.000Z"
replies: 2
views: 713
page: 1
pages: 1
language: "sv-SE"
site: "webForum — webforum.nu"
rights: "Upphovsrätten till varje inlägg tillhör dess författare."
attribution: "Citera som: webForum, https://www.webforum.nu/amne/databaser-sql/188457-mysql-join-2-ggr-på-samma-tabell-wordpress"
---

# Mysql join 2 ggr på samma tabell (wordpress)

## #1 — niska, 2011-11-21T20:38Z

Jag har en vanlig wordpress-installation.

Varje sida i min blogg motsvarar en produkt. Produkten har två priser, beroende på vilken typ det är. Dessa lagrar jag som post meta till sidan. En sida kan alltså exempelvis ha "price_current1" = "12" och "price_current2" = "10". En del sidor har endast ett pris, då lagrar jag endast "price_current1". Dessutom har sida/produkt ett orginalpris, exempelvis "price_org1" = "30" och "price_org2" = "20".

Det jag vill göra är att jag vill ta fram en lista med alla sidor/produkter som har ett pris som är lägre än orginalpris, inklusive prisskillnaden.

Tidigare har jag först selekterat fram detta i två frågor, men det jag undrar är om det är möjligt att göra det i en enda fråga så att samma produkt inte kan dyka upp två gånger.

Mina två frågor (som är nästan likadana) ser i nuläget ut så här:

```
SELECT posts.*, ROUND(A.meta_value) AS price_current,
ROUND(B.meta_value) AS price_org,
ROUND((A.meta_value / B.meta_value) * 100 - 100) AS price_diff
FROM posts, postmeta A, postmeta B WHERE ID = A.post_id
AND ID = B.post_id AND A.meta_key = 'price_current1' AND
B.meta_key = 'price_org1' AND B.meta_value > A.meta_value
AND post_status = 'publish' AND post_type = 'post' ORDER BY price_org DESC
```

```
SELECT posts.*, ROUND(A.meta_value) AS price_current,
ROUND(B.meta_value) AS price_org,
ROUND((A.meta_value / B.meta_value) * 100 - 100) AS price_diff
FROM posts, postmeta A, postmeta B WHERE ID = A.post_id
AND ID = B.post_id AND A.meta_key = 'price_current2' AND
B.meta_key = 'price_org2' AND B.meta_value > A.meta_value
AND post_status = 'publish' AND post_type = 'post' ORDER BY price_org DESC
```

Problemet jag är är alltså att samma sida/produkt kan dyka upp i båda listorna. Min förhoppning är att det går att göra allt i en enda fråga och slippa få dubletter.

Går det att slå ihop dessa två frågor till en enda fråga? Hur?

Permalänk: https://www.webforum.nu/p/188457

## #2 — aasah, 2011-11-22T22:44Z

Om jag ser rätt är enda skillnaden på de två frågorna raderna:

```
   A.meta_key = 'price_current1' AND -- resp 'price_current2' 
   B.meta_key = 'price_org1' AND  -- resp  'price_org2'
```

Stämmer det? Och i båda fallen finns det rader i posts?

Då borde följande fungera, med lite bättre joinvillkor dessutom: 

```
SELECT 
   posts.*, 
   IFNULL(ROUND(C1.meta_value), 0) AS price_current1,
   IFNULL(ROUND(O1.meta_value), 0) AS price_org1,
   IFNULL(ROUND((C1.meta_value / O1.meta_value) * 100 - 100), 0) AS price_diff1,
   IFNULL(ROUND(C2.meta_value), 0) AS price_current2,
   IFNULL(ROUND(O2.meta_value), 0) AS price_org2,
   IFNULL(ROUND((C2.meta_value / O2.meta_value) * 100 - 100), 0) AS price_diff2
FROM 
   posts P 
   LEFT JOIN postmeta C1 ON 
      P.ID = C1.post_id  AND   
      C1.meta_key = 'price_current1' 
   LEFT JOIN postmeta O1 On
      P.ID = O1.post_id  AND   
      O1.meta_key = 'price_org1' AND
      O1.meta_value > C1.meta_value 
   LEFT JOIN postmeta C2 ON 
      P.ID = C2.post_id  AND   
      C2.meta_key = 'price_current2' 
   LEFT JOIN postmeta O2 On
      P.ID = O2.post_id  AND   
      O2.meta_key = 'price_org2' AND
      O2.meta_value > C2.meta_value 
WHERE 
   P.post_status = 'publish' AND 
   P.post_type = 'post'
ORDER BY 
   P.price_org DESC
```

Då får du ut en rad per produkt i posts, medan man har räknat ut jämförelsen om det fanns uppgifter i "1 resp 2"-fallen och annars blir beräkningarna NULL. IFNULL(x, 0) = x om x is not null och 0 annars. Om du hellre vill att kolumnerna blir NULL i det läget kan du ta bort den yttre funktionen \[IFNULL(...., 0)\].

Permalänk: https://www.webforum.nu/p/2288681

## #3 — niska, 2011-11-23T10:40Z

Stort tack för svar. Jag löste det precis på ett annat sätt. Det var lättare än vad jag trodde. Det räckte med en OR på rätt ställe  :p

```
SELECT posts.*,
ROUND(A.meta_value) AS price_current,
ROUND(B.meta_value) AS price_org,
ROUND((A.meta_value / B.meta_value) * 100 - 100) AS price_diff
FROM posts, postmeta A, postmeta B
WHERE ID = A.post_id AND ID = B.post_id AND ( ( A.meta_key = 'price_current2'
AND B.meta_key = 'price_org2' ) OR ( A.meta_key = 'price_current1'
AND B.meta_key = 'price_org1' ) )
AND B.meta_value > A.meta_value
AND post_status = 'publish'
AND post_type = 'post'
ORDER BY price_org DESC
```

Permalänk: https://www.webforum.nu/p/2288712

---

Tråden på webben: https://www.webforum.nu/amne/databaser-sql/188457-mysql-join-2-ggr-på-samma-tabell-wordpress
