2014-10-26 4 views
0

я написал SQL-запрос с внутренним соединением и суб-запроса:Дублируемое имя столбца SQL - нужно изменить псевдоним?

SELECT c.*, 
     ar.ArticleName, 
     ar.idArticle, 
     du.DetailToUsersName, 
     du.DetailToUsersPhoto, 
     COUNT(c.idCommentToArticle) AS CNT, 
     CASE WHEN d.Count IS NULL THEN 0 ELSE d.Count END AS CountLikes 
from (select * 
     from commenttoarticle g 
     inner join (select distinct(s.idCommentToArticle) 
        from commenttoarticle s 
        order by s.CommentToArticlePID limit 3) as gh) as c 

LEFT JOIN article ar ON c.CommentToArticleIdArticle = ar.idArticle 
LEFT JOIN detailtousers du ON du.idDetailToUsers = c.CommentToArticleIdUser 
LEFT JOIN `likes` d ON (d.IdNote = c.idCommentToArticle AND d.LikeType = 6) 
WHERE c.CommentToArticleIdArticle = 11 
GROUP BY c.idCommentToArticle 
ORDER BY c.idCommentToArticle DESC 

Таким образом, я получаю сообщение об ошибке:

Duplicate column name 'idCommentToArticle'

Я не могу найти, где дублирование?

+0

Возможно, из-за выбора * производной таблицы c –

+0

Hm, что я должен указать вместо '*' все имена полей? – AllenDegrud

+0

Дублирование является результатом внутреннего запроса непосредственно после первого FROM. Вы присоединяете 'commenttoarticle g' к подзапросу, который возвращает только idCommentToArticle. Когда вы выполняете 'SELECT *' на этом, он принимает все поля из 'g' и вашего подзапроса и пытается псевдоним имени поля для внешнего запроса' c'. Это то место, где он не может создать псевдоним, потому что он есть в обоих. Когда вы пытаетесь ссылаться на 'c.idCommentToArticle', он не может определить, означает ли вы из псевдонима таблицы' g' или подзапроса. –

ответ

0

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

Вот моя попытка полного решения (обратите внимание, без определения набора данных и таблицы я не могу показать, что он работает). Хорошо, так что вы снова задали вопрос по here и предоставили SQL-Fiddle, я обновил рабочую версию, но минус дополнительные таблицы JOIN, так как они не определены.

SELECT c.*, 
     ar.ArticleName, 
     ar.idArticle, 
     du.DetailToUsersName, 
     du.DetailToUsersPhoto, 
     COUNT(c.idCommentToArticle) AS CNT, 
     CASE WHEN d.Count IS NULL THEN 0 ELSE d.Count END AS CountLikes 
FROM commenttoarticle c -- one layer of subquery not required. 
INNER JOIN (select s.idCommentToArticle, s.CommentToArticlePID -- added both the id and the parent id 
      FROM commenttoarticle s 
      WHERE s.CommentToArticleIdArticle = 11 -- moved to inner query, instead of outer query 
      ORDER BY s.idCommentToArticle DESC limit 3) as gh 
     ON c.idcommenttoarticle = gh.idcommenttoarticle -- add join condition 
     OR c.idcommenttoarticle = gh.CommentToArticlePID -- which matches id and parent id 

LEFT JOIN article ar ON c.CommentToArticleIdArticle = ar.idArticle 
LEFT JOIN detailtousers du ON du.idDetailToUsers = c.CommentToArticleIdUser 
LEFT JOIN `likes` d ON (d.IdNote = c.idCommentToArticle AND d.LikeType = 6) 

GROUP BY c.idCommentToArticle 
ORDER BY c.idCommentToArticle DESC 

Но позвольте мне объяснить немного дальше, следующий код из исходного запроса был выбор топ 3 idCommentToArticlePID,

(select * 
    from commenttoarticle g 
    inner join (select distinct(s.idCommentToArticle) 
      from commenttoarticle s 
      order by s.CommentToArticlePID limit 3) as gh) 

, но потом, потому что было не ON не указаны 3 записи были затем присоединились к каждой отдельной записи из справочника g. Это привело к возврату полного набора данных.

И тогда вы указали WHERE c.CommentToArticleIdArticle = 11, это отфильтровало результирующий набор обратно на то, что выглядело правильно.

Когда вы добавили ON (согласно предложению RADAR), внутренний запрос не содержал никаких значений, которые соответствовали бы фильтру , и таким образом вы потеряли все свои результаты. Если вы переместите этот фильтр во внутренний запрос, как показано выше, они будут работать вместе, а не конфликтуют.

В рамках условия JOIN вы указываете, что хотите как соответствующие статьи, так и их родители, поэтому я добавил оба к возврату внутреннего запроса и проверил либо в условии соединения.

Также я думаю, что вся ссылка на таблицу g является избыточной и может быть удалена. Вы должны иметь доступ к этой таблице непосредственно как c.

У меня также есть некоторые сомнения по поводу GROUP BY и COUNT (c.idCommentToArticle) - кажется немного странным, но у меня нет вспомогательного контекста (например, примеров данных), поэтому они могут быть правильными. Если у вас все еще есть проблемы, я бы прокомментировал выдержки GROUP BY и COUNT и проверил, какие данные вы получаете, прежде чем добавлять их обратно.

+0

Неправильный результат в любом типе вашего примера. Я проверил. Первый запрос возвращает все строки и условие WHERE. – AllenDegrud

+0

@AllenDegrud - В то время я работал над обновлением. вы хотите попробовать еще раз? см. SQL Fiddle рядом с ответом. –

2

вы можете указать в псевдоним таблицы запроса с

select g.* from commenttoarticle g 

вместо

select * from commenttoarticle g 

Также следует указать условие соединения, чтобы ограничить строки до 3 в соответствии с вашим намерением, с вне ON это будет похоже на перекрестное соединение.

select g.* from commenttoarticle g 
inner join (select distinct(s.idCommentToArticle) from commenttoarticle s order by s.CommentToArticlePID limit 3) as gh 
    on g.idcommenttoarticle = gh.idcommenttoarticle 
+0

@allendegrud, добавить условие соединения, как я упомянул – radar

+0

Да, это правильный ответ. Но если я укажу 'Join condition', я не получаю строки, где' PID> 0', только первые 3 строки 'WHERE PID = 0', Итак, мне нужно получить строки PID и PID'S строк. – AllenDegrud

+0

Я ответил на 'PID, ID' здесь: http://stackoverflow.com/questions/26575283/why-operator-limit-does-not-work-correctly Но никто не мог мне помочь – AllenDegrud