MySQLで検索クエリを実行して、製品と価格表のテーブルからアイテムを返しています。ユーザーが検索クエリを実行すると、製品テーブルLEFT JOINEDから製品を取得する必要があり、2番目のテーブル(任意の数の販売者)のすべての承認済み/ロック解除済み販売者を指定します。
基本的な検索クエリは機能していますが、「動的LEFT JOIN」を機能させることができません。私はこれをprepステートメントで行うように言われました。これは(a)非常に苦労している(初めて)作業時にどこに置くべきかわかりません。
私の検索クエリは次のようになります。
SELECT articles AS art
<< need to left join here >>
FROM bigtable AS bt
WHERE
a lot of other criteria
これは私が思いついた準備文です:
SET @sql_text := '
DECLARE strCount INT DEFAULT 1;
SELECT sid, ifnull(pricelist,"BASE"), count(*) AS recs
FROM buyerList AS b
LEFT JOIN sellerList AS s ON s.sid = b.sid AND s.pass = b.pass
WHERE b.bid = ?
SET @string = "LEFT JOIN preislisten AS p";
lj:
LOOP
SET @string = CONCAT( @string, "ON (p.iln = a.iln AND p.preisliste = sid AND p.ean = a.ean AND p.iln = pricelist ) OR");
SET strCount = strCount+1;
IF strCount = recs
THEN LEAVE lj;
END IF;
END LOOP lj;
SET @string = CONCAT( @string,"(1=0)")
';
SET @param_iln = param_iln;
PREPARE stmt FROM @sql_text;
EXECUTE stmt using @param_iln;
DEALLOCATE PREPARE stmt;
だから私は基本的にすべての出品者とpricelist-name(デフォルトはBASE)を見つけて、次のような文字列を作成しようとします:
LEFT JOIN pricelists p ON
(p.sid = a.sid AND p.pricelist = "foo" AND p.ean = a.ean AND p.iln = 23467 ) OR
(p.sid = a.sid AND p.pricelist = "bar" AND p.ean = a.ean AND p.iln = 99999) OR
...
(1=0)
私の質問:
(1)25のセラーがある場合、25ループしますが、このように正しいセラーと価格リストが私の文字列に挿入されますか?
(2)これを実際の検索クエリに挿入するにはどうすればよいですか?実行すると、文字列が返される場合がありますが、文字列をクエリに入れることはできませんか?
簡単にしてくれてありがとう...最初の準備ステートメント、2週目のMySQL ...
編集:
これが私が思いついたものです:
# bigtable query
SELECT count(a.id) AS gesamt_datensaetze, a.nos, a.nos_anzeige
FROM artikelstammdaten AS a
#JOIN colors
LEFT JOIN farbenzuordnung AS zu
ON a.farbe = zu.farbe
AND ( ( param_filter = '' ) AND (1=1) OR ( zu.ILN = param_filter ) )
# ========== NEW PART ==========
LEFT JOIN preislisten AS p
ON ( p.iln = a.iln
AND p.EAN = a.EAN
AND p.preisliste = ( #NEW GET pricelists
SELECT IFNULL(klhs.preisliste, "-Standard-") AS pricelistID
FROM kundenliste_haendler AS klhd
LEFT JOIN kundenliste_hersteller AS klhs
ON klhs.iln = klhd.iln_verkaeufer
AND klhs.plz = klhd.plz
AND klhs.cid= klhd.cid
WHERE klhd.iln_kaeufer = param_iln
GROUP BY pricelistID
)
AND p.iln = ( #GET seller
SELECT klhd.iln_verkaeufer AS sellerID
FROM kundenliste_haendler AS klhd
LEFT JOIN kundenliste_hersteller AS klhs
ON klhs.iln = klhd.iln_verkaeufer
AND klhs.plz = klhd.plz
AND klhs.cid= klhd.cid
WHERE klhd.iln_kaeufer = param_iln
GROUP BY pricelistID
)
)
# active
WHERE a.aktiv = "ja"
# more criteria
これが正しく機能するかどうかを確認するまで。私の(同一の)入れ子になった選択を1つの入れ子になった選択に組み合わせることができるかどうかに関する洞察を誰かが放てれば、それは大歓迎です!
質問から、あなたが書いたものは、Oracleが匿名コードブロックと呼ぶものに似ています。 MySQLはそのようなメカニズムを促進しません。
達成したいことに関しては、ストアドプロシージャは必要ありません。
次のようにSQLステートメントを組み立ててみてください。
@stmt = 'SELECT sid, ifnull(pricelist,"BASE"), count(*) AS recs FROM buyerList AS b ';
@stmt = CONCAT(@stmt,'LEFT JOIN sellerList AS s ON s.sid = b.sid AND s.pass = b.pass ');
@stmt = CONCAT(@stmt,'LEFT JOIN pricelists p ON ');
SELECT GROUP_CONCAT(CONCAT('(p.sid = a.sid AND p.preisliste = ',sid,' AND p.ean = a.ean AND p.iln = ',pricelist',)') SEPARATOR ' OR ')
INTO @LeftJoinClause FROM preislisten;
@stmt = CONCAT(@stmt,@LeftJoinClause,' WHERE b.bid = ?');
SELECT @stmt\G
これにより、目的のクエリが出力されます
必要なクエリである場合は、実行します
PREPARE sql FROM @stmt;
EXECUTE sql using @param_iln;
DEALLOCATE PREPARE sql;
試してみる !!!
すべての値をハードコーディングせずにクエリを実際に小さくしたい場合は、より単純なLEFT JOIN設定でコードを記述します。
SELECT p.sid, ifnull(p.pricelist,"BASE"), count(*) AS recs FROM buyerList AS b
LEFT JOIN sellerList AS s ON s.sid = b.sid AND s.pass = b.pass
LEFT JOIN pricelists p ON
(p.sid = a.sid AND p.preisliste = a.sid AND p.ean = a.ean)
WHERE b.bid = ?
GROUP BY p.sid,p.pricelist;
また、a.sidとa.eanがあることに気づきました。どのテーブルにa
のエイリアスがありますか?
SELECTS内でsprocsを実行するという技術的な質問に焦点を当てています。
インラインSQLとストアドプロシージャのコンテキストが異なる動物であることを示すテストを作成しました。
mysql> delimiter $$
mysql> CREATE PROCEDURE test123 ()
-> begin
-> SELECT NOW();
-> end;
-> $$
Query OK, 0 rows affected (1.04 sec)
mysql> delimiter ;
mysql> call test123();
+---------------------+
| NOW() |
+---------------------+
| 2012-06-21 08:58:15 |
+---------------------+
1 row in set (0.04 sec)
Query OK, 0 rows affected (0.04 sec)
mysql> SELECT t.* FROM ( call test123() ) t;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'call test123() ) t' at line 1
mysql> SELECT ( call test123() ) AS t;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'call test123() ) AS t' at line 1