SQL Запрос с двумя таблицами и необходимость поиска в одной из таблиц указанного c и нескольких значений столбца - PullRequest
0 голосов
/ 17 июня 2020
• 1000 1003 *
Table 1:
ID | Type | Size
A123 | Block | Medium
C368 | Square | Large
X634 | Triangle | Small
K623 | Square | Small
Table 2:
ID | Code | Description | Price
A123 | C06 | Sensitive Material | 99.99
A123 | H66 | Heavy Grade | 12.76
A123 | U74 | Pink Hue | 299.99

C368 | H66 | Heavy Grade | 12.76
C368 | G66 | Green Hue | 499.99
C368 | C06 | Sensitive Material | 99.99
C368 | K79 | Clear Glass | 59.99

X634 | G66 | Green Hue | 499.99
X634 | K79 | Clear Glass | 59.99
X634 | Z63 | Enterprise Class | 999.99

K623 | K79 | Clear Glass | 59.99
K623 | G66 | Green Hue | 499.99
K623 | X57 | Extra Piping | 199.99

Запрос должен быть основан в первую очередь на столбце Type из таблицы 1, а затем присоединяться к столбцу ID таблицы 2. Цель запроса - найти все идентификаторы в Таблице 1, в которых указаны комбинации c Code столбцов в Таблице 2.

Конечным результатом должна быть таблица, которая выглядит следующим образом для Тип = Квадрат И оба (Код = G66 И Код = K79) а также:

ID 
C368
K623

Эти два идентификатора должны быть возвращены, потому что оба они имеют ОБЕИХ коды опций в приведенном выше псевдозапросе.

Как я могу собрать этот результат, используя эти две таблицы? Ниже приведены два начальных запроса, которые я написал - ни один из них не дает правильного результата. Я пробовал оператор IN вместе с операторами = / AND / OR, как вы можете видеть.

Попытка 1 (похоже, работает с ОДНИМ кодом, но не с кодом> 1):

select distinct ID
from
(
SELECT shapes.ID, details.code, details.description
FROM db.table2 details 
JOIN db.table1 shapes
ON details.VIN = shapes.VIN
WHERE shape.type='Square'
) src
where code IN ("G66", "K79")
-- where code = "G66" AND code = "K79" (Produces zero results)
-- where code = "G66" OR code = "K79" (Produces incorrect results)

Попытка 2 (похоже, работает с ОДНИМ кодом, но не с кодом> 1):

SELECT distinct ID
FROM db.table2 details
WHERE ID IN
(
    SELECT ID FROM db.table1 shapes 
    WHERE shapes.type='Square' 
) AND code IN ("G66", "K79")
-- AND code = "G66" AND code = "K79" (produces zero results)
-- AND code = "G66" OR code = "K79" (Produces incorrect results)

Спасибо

Ответы [ 3 ]

1 голос
/ 17 июня 2020

Всякий раз, когда у вас возникает проблема типа «Мне нужны идентификаторы из этой таблицы, где есть одна строка со значением A, а другая строка со значением B, и обе строки имеют тот же идентификатор», вам нужно выбрать все строки, соответствующие вашим критериям, сгруппируйте их, а затем подсчитайте и используйте только те строки, которые имеют соответствующий счетчик:

SELECT t2.id
FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id
WHERE t1.type = 'square' and t2.code IN ('G66', 'K79')
GROUP BY t2.id
HAVING COUNT(*) = 2

Если могут быть какие-то поддельные результаты, такие как две строки, которые являются G66, и нет строк, которые K79, тогда этот простой подсчет будет проигран. Вместо этого мы можем посмотреть значения (если это 2), используя MIN и MAX:

SELECT t2.id
FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id
WHERE t1.type = 'square' and t2.code IN ('G66', 'K79')
GROUP BY t2.id
HAVING MIN(t2.code) = 'G66' AND MAX(t2.code) = 'K79'

Это работает, потому что по алфавиту G66 меньше K79, поэтому G66 будет минимальным

Если у нас есть 3 значения, которые мы должны указать, мы можем сделать какой-нибудь трюк, например, превратить все коды в число и потребовать, чтобы сумма была чем-то. Я буду использовать для этого базу 2:

SELECT t2.id
FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id
WHERE t1.type = 'square' and t2.code IN ('G66', 'K79', 'X99')
GROUP BY t2.id
HAVING SUM(CASE t2.Code WHEN 'G66' THEN 1 WHEN 'K79' THEN 2 WHEN 'X99' THEN 4 END) = 7

Если мы сопоставим их с 1, 2 и 4, тогда единственный способ получить 7 (если значения уникальны) - иметь по одному из каждого. Если бы могло быть 7 G66 и ни один из остальных, дающих ложный результат, тогда нам, возможно, пришлось бы считать их по отдельности:

SELECT t2.id
FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id
WHERE t1.type = 'square' and t2.code IN ('G66', 'K79', 'X99')
GROUP BY t2.id
HAVING 
  SUM(CASE t2.code WHEN 'G66' THEN 1 ELSE 0 END) = 1 AND
  SUM(CASE t2.code WHEN 'K79' THEN 1 ELSE 0 END) = 1 AND
  SUM(CASE t2.code WHEN 'X99' THEN 1 ELSE 0 END) = 1 
0 голосов
/ 17 июня 2020

Не могли бы вы просто использовать INNER JOIN для идентификаторов из таблицы 1 после получения соответствующих строк, которые имеют тип, который мы ищем, поскольку таблица 1 и таблица 2 связаны по идентификатору?

Я полагаю, мы могли бы сначала выполнить запрос, чтобы получить все строки, которые имеют соответствующий тип, а затем запустить INNER JOIN, чтобы получить общие строки, которые имеют идентификатор, который нам нужен.

Наконец, мы могли бы просто сгруппировать наши результаты по их столбцу кода?

Может, что-то вроде этого могло бы сработать?:

SELECT * FROM db.table1 WHERE db.table1.type = "whatever"
INNER JOIN db.table2 ON db.table1.id = db.table2.id
GROUP BY db.table2.code HAVING COUNT(*) >= 1
AND db.table2.code IN ("code_1, code_2, code_3")

Я только что начал SQL так что я надеюсь на это!

PS Я понял, что не покрыл ваше условие для того, чтобы код был членом подмножества кодов, которое вам небезразлично. Думаю, это может сработать.

0 голосов
/ 17 июня 2020

Вот что я думаю.

Отфильтруйте данные из t1 с помощью предложения where, затем присоединитесь к t2, 2 раза, каждый из которых будет отфильтрован по условиям, чтобы G66 и K79 были в одной таблице (2 разных соединения )

Select t1.ID 
from t1 
inner join t2 as t2_G66 on t1.ID = t2_G66.ID
inner join t2 as t2_K79 on t1.ID = t2_K79.ID
where t1.Type = 'Square' and 
    t2_G66.Code = 'G66' and 
    t2_K79.Code = 'K79' 

Вот скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...