我试图一次访问不同表中的数据,但我希望能够确定哪个表从另一个表中的列值中提取数据。
以下是一个例子:
表A:(id,table1_id,table1_type,table2_id,table2_type)
表B:(id,some_values):
表C,D和E看起来有点类似于B.
所以,我想做以下(在伪javascript中完成):
result = db.Query("SELECT * from A WHERE [condition] LIMIT 1")
table1 = getTable(result.table1_type) // E.g. 'B' if 'B_Type'
table2 = getTable(result.table2_type)
new_results = db.Query("SELECT * from " + table1 + ", " + table2 + " WHERE [condition]")
这种方式有效,但我希望有一种方法可以根据A的table_type列有条件地选择表。
任何帮助都将不胜感激。
答案 0 :(得分:2)
如果你真的想这样做,你需要所有多连接中最丑的:
SELECT
IF(A.table1_type='B',B1.some_value,
IF(A.table1_type='C',C1.some_value,
IF(A.table1_type='D',D1.some_value,
IF(A.table1_type='E',E1.some_value,
NULL)))) AS table1_value,
IF(A.table2_type='B',B2.some_value,
IF(A.table2_type='C',C2.some_value,
IF(A.table2_type='D',D2.some_value,
IF(A.table2_type='E',E2.some_value,
NULL)))) AS table2_value
FROM A
LEFT JOIN B AS B1 ON A.table1_type='B' AND A.table1_id=B1.id
LEFT JOIN C AS C1 ON A.table1_type='C' AND A.table1_id=C1.id
LEFT JOIN D AS D1 ON A.table1_type='D' AND A.table1_id=D1.id
LEFT JOIN E AS E1 ON A.table1_type='E' AND A.table1_id=E1.id
LEFT JOIN B AS B2 ON A.table2_type='A' AND A.table2_id=B2.id
LEFT JOIN C AS C2 ON A.table2_type='B' AND A.table2_id=C2.id
LEFT JOIN D AS D2 ON A.table2_type='C' AND A.table2_id=D2.id
LEFT JOIN E AS E2 ON A.table2_type='D' AND A.table2_id=E2.id
WHERE [condition for A];
修改强>
有些解释说明:MySQL(与大多数SQL数据库一样)没有“预期”的方式来动态切换表。这使得有必要加入所有表,然后删除除一个结果之外的所有表。为您的用例重复两次。
答案 1 :(得分:0)
如果你想避免做一堆连接,你应该能够使用游标和一些动态SQL来完成这个。
以下是一个示例(这是使用MSSQL语法编写的,但我认为它在MySql中关闭,如果不相同):
CREATE TABLE #result
(table1Val varchar(50), table2Val varchar(50))
DECLARE @sql VARCHAR(MAX)
DECLARE @table1_val int, @table1_type varchar(50), @table2_val int, @table2_type varchar(50)
DECLARE cur CURSOR FOR
SELECT table1_id, table1_type, table2_id, table2_type
FROM A
OPEN cur
FETCH NEXT FROM Cur INTO @table1_val, @table1_type, @table2_val, @table2_type
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = '
INSERT INTO #result
(SELECT val FROM ' +CASE @table1_type WHEN 'B_Type' THEN 'B' WHEN 'C_type' THEN 'C' + ' WHERE id = '''+@table1_val+'''),
(SELECT val FROM ' +CASE @table2_type WHEN 'B_Type' THEN 'B' WHEN 'C_type' THEN 'C' + ' WHERE id = '''+@table2_val+''')
'
EXEC(@sql)
--use this instead to debug the dynamic query
--PRINT(@sql)
END
UPDATE @JoinResult
SET B_ID = SQ.ID,
B_Age = SQ.AGE,
B_Education = SQ.Education
FROM (
SELECT ID, AGE, EDUCATION
FROM TableB b
WHERE (
abs((SELECT A_Age FROM @JoinResult WHERE A_Id = @i) - AGE) <=2
AND abs((SELECT A_Education FROM @JoinResult WHERE A_Id = @i) - EDUCATION) <=2
) AND (SELECT B_ID FROM @JoinResults WHERE B_ID = b.id) IS NULL
) AS SQ
CLOSE cur
DEALLOCATE cur
SELECT #result
DROP TABLE #result