SQL: основы соединений и других таблиц - PullRequest
0 голосов
/ 13 декабря 2011

Я думаю, мне нужен намек в каком направлении идти.В продолжение моего другого вопроса я пытаюсь реализовать SQL-запрос для 3 таблиц с MySQL .

Таблица 1: "базовая" информация о продукте

id, productnumber
1,45

Таблица 2: "country_specifics" для каждого идентификатора продукта

id, countrycode,name
1,"DE","Produkt 1"
1,"US","Product 1"

Хорошо,

SELECT B.id,C.name,C.countrycode 
FROM base AS B 
INNER JOIN country_specifics AS C ON B.id=C.id
WHERE B.id=1 AND C.countrycode='US';

дает мне то, что я хочу:

1,"Product 1","US"

НО:

У меня есть третья таблица:

Таблица 3: «функции» для каждого идентификатора продукта

id,feature
1,"feature 1"
1,"feature 2"

и конечный результат моего запроса должен как-то дополнительно содержать характеристики продукта.Я попробовал это с дополнительным

INNER JOIN features AS F ON b.id=f.id

, но это вернет две строки (и я понимаю почему):

1,"Product 1","US","feature 1"
1,"Product 1","US","feature 2"

, но я думаю, что это не то, что я хочу.То, что я хочу, это своего рода массив для поля компонента:

1, «Продукт 1», «США», «функция 1, функция 2»

в результате.Я знаю (или почти уверен), что в SQL нет массивов, но что ближе к этому?Могу ли я сделать это в 1 запросе?Очевидно, я мог бы просто начать второй запрос, но это лучший вариант?По какому ключевому слову я должен гуглить?

Спасибо за чтение, Маримба

РЕДАКТИРОВАТЬ

Спасибо всем за помощь, правда!

Я просто хотел бы уточнить мой вопрос: мне не обязательно нужен массив или что-то близкое к нему.Я хотел бы понять, какой наилучший (наиболее эффективный, наименее подверженный ошибкам) ​​подход заключается в получении «всех данных для этого продукта».

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

РЕДАКТИРОВАТЬ 2:

Опять же, я извиняюсь за то, что вводил людей в заблуждение, заставляя их думать, что мне нужна строка, разделенная запятыми.Я попытался проиллюстрировать, какие именно данные я ожидал.

Я ценю указатель на group_concat, но у меня такое ощущение, что stored procedure с двумя запросами, как обрисовано в общих чертах jmacinnes и Sachin, является более чистымway.

Спасибо, сообщество stackoverflow.

Ответы [ 5 ]

2 голосов
/ 13 декабря 2011

Вы можете написать функцию или хранимую процедуру, которая принимает идентификатор, а затем для таблицы объектов возвращает строку со всеми объектами с этим идентификатором.Затем вы можете использовать это в исходном запросе.

1 голос
/ 13 декабря 2011

Приведенное ниже решение основано на Oracle, вы можете попробовать реализовать то же самое в MySQL

, вы можете создать функцию базы данных, как показано ниже

create or replace function prod_feature(p_product_id in number) return varchar2
    v_feature varchar2(2000) := '';
    i number := 0 ;
begin
    for c1rec in (select feature from table3 where product_id = p_product_id) loop
       if i = 0 then
           v_feature:= v_feature|| c1rec.feature;
       else
           v_feature:= v_feature|| ', ' || c1rec.feature;
       end if;
       i  := i +1;
    end loop;
    return v_feature;
end; 

, затем использовать эту функцию в первом sql

SELECT B.id,C.name,C.countrycode, prod_feature(id) 
FROM base AS B 
INNER JOIN country_specifics AS C ON B.id=C.id
WHERE B.id=1 AND C.countrycode='US';
1 голос
/ 13 декабря 2011

Поскольку вы используете MySQL, вы можете использовать group_concat:

SELECT B.id,C.name,C.countrycode, group_concat(F.feature) as feature_list 
FROM base AS B 
INNER JOIN country_specifics AS C ON B.id=C.id
WHERE B.id=1 AND C.countrycode='US'
INNER JOIN features AS F ON B.id=F.id
GROUP BY B.id
1 голос
/ 13 декабря 2011

Я думаю, вы должны сделать это, используя единственный запрос, который вы уже написали. Затем просто отформатируйте данные, которые будут отображаться так, как вы хотите на уровне приложения. Вы можете просмотреть результаты и сгруппировать все функции для каждого продукта.

Хотя можно вернуть набор результатов, который вам нужен, это было бы плохой практикой. Было бы намного сложнее анализировать данные, если бы таблица функций в будущем должна была измениться.

Если дублированные данные, которые вы получили бы, присоединившись к таблице компонентов, имеют большое значение, то вы могли бы вернуть два набора результатов в одной хранимой процедуре:

SELECT B.id,C.name,C.countrycode 
FROM base AS B 
INNER JOIN country_specifics AS C ON B.id=C.id
WHERE B.id=1 AND C.countrycode='US';

SELECT id featureId FROM features where ProductId = 1
0 голосов
/ 14 декабря 2011

Как насчет этого.Попробуйте, посмотрите, работает ли он так, как вы хотите.

SELECT id, name, code, GROUP_CONCAT(fea) features FROM 
(  
  SELECT id, name, code, f.feature fea FROM 
  (
    SELECT b.id id, cs.name name, cs.countrycode code FROM 
    base b
    JOIN country_specifics cs
    ON cs.id = b.id
    AND cs.countrycode = "US"
   ) a
 JOIN features f
 ON f.id = a.id  
) b
GROUP BY id
...