2

以下のSQLクエリがあります。

SELECT message, sent_date, user_id
FROM messages
LEFT JOIN numbers ON messages.from_id = numbers.id

テーブル内のすべての行(約4000)を返し、messagesテーブルから追加の列を取得しnumbersます。これまでのところ、これは私が期待することです。

ここで、再び左結合を使用して、このサブクエリを別のテーブルに左結合します。

SELECT message, sent_date
FROM (
    SELECT message, sent_date, user_id
    FROM messages
    LEFT JOIN numbers ON messages.from_id = numbers.id
) AS table1
LEFT JOIN users ON table1.user_id = users.id

ただし、返される行は約200行しかないため、多くの行が欠落しています。これは左結合であるため、table1のすべての行が結果に含まれると予想されます。誰かが問題が何であるかを見ることができますか?

編集:

したがって、ここでの情報は、3つの関連するテーブル(関連しない列が削除されている)です。

CREATE TABLE IF NOT EXISTS `messages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `message` text CHARACTER SET utf8 NOT NULL,
  `from_id` int(11) DEFAULT NULL,
  `sent_date` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `from_id` (`from_id`),
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=101553 ;

CREATE TABLE IF NOT EXISTS `numbers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `number` varchar(32) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6408 ;

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(256) CHARACTER SET utf8 DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2395 ;
4

5 に答える 5

2

問題をデバッグする別の方法を試すことができます。

CREATE TEMPORARY table tmp1 AS SELECT message, sent_date, user_id
                               FROM messages
                                    LEFT JOIN numbers 
                                        ON messages. from_id = numbers.id;

次に、このクエリが機能するかどうかを確認します。

 SELECT message, sent_date
 FROM tmp1 table1
      LEFT JOIN users 
          ON table1.user_id = users.id;

また、あなたの場合、間に他の挿入や更新がないことを確認してください。それ以外の場合は、トランザクションを使用します。

于 2012-08-09T10:12:43.823 に答える
1

table1 には UserID がない場合があるため、null になるため、それらの結果が欠落しますか?

于 2012-08-09T10:07:00.643 に答える
0

これが起こるはずがありません。

このバリエーションを試してください:

SELECT 
    m.message, m.sent_date, n.user_id
FROM
    messages m
  LEFT JOIN 
    numbers AS n  ON m.from_id = n.id
  LEFT JOIN 
    users AS u  ON n.user_id = u.id ;
于 2012-08-09T11:28:23.320 に答える
0

あなたの質問に対する正確な答えはありませんが、考え始める必要がある場合は、最初に3800行が欠落しているものを見つけて、パターンを確認しようとします(user_idがnullまたは重複しているためです)

SELECT message, sent_date, user_id
FROM messages
LEFT JOIN numbers ON messages.from_id = numbers.id
MINUS
(SELECT table1.message, table1.sent_date, table1.user_id
FROM (
    SELECT message, sent_date, user_id
    FROM messages
    LEFT JOIN numbers ON messages.from_id = numbers.id
) AS table1
LEFT JOIN users ON table1.user_id = users.id)
于 2012-08-09T10:29:04.883 に答える
0

これを試してみてください。これは のスコープの問題だと思いますuser_id

SELECT table1.message, table1.sent_date 
FROM ( 
    SELECT messages.message, messages.sent_date, numbers.user_id 
    FROM messages 
    LEFT JOIN numbers ON messages.from_id = numbers.id 
) AS table1 
LEFT JOIN users ON table1.user_id = users.id 

にあるかどうかuser_idはわかりません。messagesnumbers

于 2012-08-09T10:15:39.750 に答える