Как удалить декартово соединение - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть две таблицы, структура которых похожа на две таблицы ниже. Имя:

ID     | FirstName | LastName
__________________________
123     Akshay     kumar
123     Salman     khan
123     Johnny      lever
123     Tom           Cruise

Город:

ID     | City
___________
123     Pune

Теперь, когда я запускаю следующий запрос:

Select N.*,C.* from Name N,City C where C.ID=N.ID and N.ID=123; 

ID     | FirstName | LastName | ID     | City 
_____________________________________________
123     Akshay     kumar             123     Pune
123     Salman     khan               123     Pune
123     Johnny      lever               123     Pune
123     Tom           Cruise            123     Pune

Пуна повторяется 4 раза. Принимая во внимание, что я хочу вывод, как показано ниже:

ID     | FirstName | LastName | ID     | City 
_____________________________________________
123     Akshay     kumar             123     Pune
123     Salman     khan               
123     Johnny      lever               
123     Tom           Cruise   

Нет никакой связи между данными Name и City Table, кроме идентификатора Coumn. Также не обязательно, чтобы в таблице имен было больше записей, чем в таблице городов для одного и того же идентификатора. Таблица городов также может содержать больше строк, чем Таблица имен, для одного и того же идентификатора. (Таким образом, левое соединение не будет работать). Пожалуйста, помогите парням.

Ответы [ 3 ]

0 голосов
/ 01 апреля 2020

Вы не хотите удалять декартово произведение.

Вы действительно хотите поставить «паузу» в своей отчетности. С Oracle сделайте следующее:

break on city

С MySql вам не повезло. У него нет такой конструкции без некоторого нетривиального кодирования. См. Этот ответ: mySQL добавление данных о разрыве столбцов .

Для других инструментов отчетности методика будет различной, но, пожалуйста, поймите, что вы на самом деле задаете вопрос об отчетности, а не SQL вопрос, и нужная вам структура отчетности - это «разрыв», иногда называемый «разрыв управления».

0 голосов
/ 01 апреля 2020

Вы можете использовать аналитическую функцию row_number следующим образом:

select n.id, n.firstname, n.lastname, c.id, c.city, 
(select t.*, row_number() over (partition by id order by t.firstname) as rn  from name t) n
left join
(select t.*, row_number() over (partition by id order by t.city) as rn  from city t) c
on n.id = c.id and n.rn = c.rn
order by n.id, n.rn
0 голосов
/ 01 апреля 2020

Это требование, которое обычно обрабатывается на уровне презентации, например, PHP или любым другим инструментом, использующим вашу базу данных. При этом мы можем удовлетворить ваши требования, используя ROW_NUMBER:

WITH cte AS (
    SELECT n.FirstName, n.LastName, c.ID, c.City,
        ROW_NUMBER() OVER (PARTITION BY c.ID, c.City ORDER BY n.LastName, n.FirstName) rn
    FROM Name n
    INNER JOIN City c ON c.ID = n.ID
    WHERE n.ID = 123
)

SELECT ID, FirstName, LastName,
    CASE WHEN rn = 1 THEN ID END AS ID,
    CASE WHEN rn = 1 THEN City END AS City
FROM cte
ORDER BY
    ID,
    LastName,
    FirstName;
...