Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 计算要从行值联接的表名_Sql_Sqlite - Fatal编程技术网

Sql 计算要从行值联接的表名

Sql 计算要从行值联接的表名,sql,sqlite,Sql,Sqlite,我有一些看起来有点像这样的表格: Table name: products ID PRODUCT_ID TYPE PRICE ... 1 111 computer xxx 2 222 book xx 3 333 computer xxxx -------------------------------------------

我有一些看起来有点像这样的表格:

Table name: products

ID      PRODUCT_ID      TYPE       PRICE      ...
1       111             computer   xxx
2       222             book       xx
3       333             computer   xxxx

----------------------------------------------------------------

Table name: products_computer

ID      PRODUCT_ID      CPU     RAM      ....
1       111             amd     16
2       333             intel   8

----------------------------------------------------------------

Table name: products_book

ID      PRODUCT_ID      AUTHOR          YEAR_PUBLISHED        ....
1       222             Stephen King    xxxx
如您所见,在表
products
中,每个产品都列出了它们的共同点(如价格),其他表包含该产品类型的特定信息

现在让我们假设我们想列出每一种产品,它们的类型与价格无关,并且在查询中包含
products.*
表的特定信息,而不是手动进行第二次查询来检索该信息

虽然我几乎不使用数据库和SQL,但我的经验不足,在尝试使用字符串为
连接构建
产品*
表名或创建将
products.TYPE
值映射到实际表名的“中间表”时遇到了各种陷阱,我在后面的文档中发现,尝试将列/行值“绑定”为表名根本不起作用

有没有什么“技巧”可以让这项工作正常进行(所有内容都在一个查询中),或者我真的必须在代码中手动进行第二个查询?

这可以通过语句实现

SELECT 
    products.ID AS ID, products.PRODUCT_ID AS PRODUCT_ID, products.PRICE AS PRICE, products_computer.CPU AS CPU, products_computer.RAM AS RAM,
    null as AUTHOR, null as YEAR_PUBLISHED
  FROM products_computer
  JOIN products ON products_computer.PRODUCT_ID = products.PRODUCT_ID
UNION
SELECT 
    products.ID AS ID, products.PRODUCT_ID AS PRODUCT_ID, products.PRICE AS PRICE, null as CPU, null as RAM, 
    products_book.AUTHOR AS AUTHOR, products_book.YEAR_PUBLISHED AS YEAR_PUBLISHED 
  FROM products_book
  JOIN products ON products_book.PRODUCT_ID = products.PRODUCT_ID
ORDER BY PRICE  
这两个独立的查询被合并到一个较大的查询中。要使其工作,在每个
SELECT
语句中选择的列必须相同。注意我是如何为另一个表中的列选择空值的

每个
SELECT
s也基于公共产品ID列连接回
products
。价格包括在内,最后有一个按价格排序的声明

这是查询的输出:

根据@Zero的评论,可以将查询存储为视图。作为一次性操作,将查询作为视图定义执行:

CREATE VIEW vw_products_all AS
       SELECT products.ID AS ID,
              products.PRODUCT_ID AS PRODUCT_ID,
              products.PRICE AS PRICE,
              products_computer.CPU AS CPU,
              products_computer.RAM AS RAM,
              NULL AS AUTHOR,
              NULL AS YEAR_PUBLISHED
         FROM products_computer
              JOIN products
                ON products_computer.PRODUCT_ID = products.PRODUCT_ID
       UNION
       SELECT products.ID AS ID,
              products.PRODUCT_ID AS PRODUCT_ID,
              products.PRICE AS PRICE,
              NULL AS CPU,
              NULL AS RAM,
              products_book.AUTHOR AS AUTHOR,
              products_book.YEAR_PUBLISHED AS YEAR_PUBLISHED
         FROM products_book
              JOIN products
                ON products_book.PRODUCT_ID = products.PRODUCT_ID
        ORDER BY PRICE;
。。。之后,可通过以下方式访问数据:

SELECT * FROM vw_products_all
。。。或者更明确地说(良好实践):


输出与原始查询的输出相同。

如果我理解正确,那么您需要
产品
表中的所有列,以及
产品计算机
产品手册
表中的相应信息(如果有)

如果是这种情况,那么我认为这里只需要多个
LEFT-JOIN
SQL语句

SQL语句

SELECT products.product_id, type , price, cpu, ram, author, year_published
FROM products
LEFT JOIN products_computer ON products.product_id = products_computer.product_id
LEFT JOIN products_book ON products.product_id = products_book.product_id
ORDER BY price
输出

。生成一个将所有这些表放在一起的视图相当容易。试试这个:

DECLARE @SQL NVARCHAR(MAX) = 'CREATE VIEW vw_products_all AS ' +
    SUBSTRING((
        SELECT [text()] = REPLACE(REPLACE(REPLACE(
            ' UNION ALL {1}SELECT P.id, P.PRODUCT_ID, P.Name, {2} FROM dbo.products AS P INNER JOIN dbo.{0} AS PS ON P.PRODUCT_ID = PS.PRODUCT_ID'
            , '{0}', QUOTENAME(O.name))
            , '{1}', CHAR(10))
            , '{2}', SUBSTRING((
                SELECT [text()] = ', ' + ISNULL(QUOTENAME(C_this.name), 'NULL as ' + QUOTENAME(C_all.name))
                FROM sys.columns AS C_all
                    LEFT JOIN sys.columns AS C_this
                        ON O.object_id = C_this.object_id
                        AND C_all.name = C_this.name
                WHERE OBJECT_NAME(C_all.object_id) LIKE 'product[_]%'
                    AND c_all.name NOT IN ('PRODUCT_ID', 'ID')
                ORDER BY C_all.name
                FOR XML PATH('')
            ), 2, 10000000000000))
        FROM sys.objects AS O
        WHERE name LIKE 'product[_]%'
        FOR XML PATH('')
    ), 11, 1000000000000)

SELECT @SQL

在你的例子中,我真的无法理解产品是如何按价格订购的。而且,这使我写出了所有的列和具体的
产品*
表格,其中的内容远远超过了我在问题中的缩小版。这可能会成为某个查询的怪物,而不是迟早。@Slyps您可以将查询作为“视图”存储在数据库本身中。“视图”不包含任何实际数据(仅包含查询),但可以像普通表一样使用它。这个
view
确实很有趣,但它在为这种情况创建查询字符串的大小和工作量问题上并没有真正的帮助。如果有50种以上的产品类型(因此有50种以上的
product.*
tables),该怎么办。我无法想象这在SQL pros的世界中会是一个好的实践(与在迭代
产品
表的结果时创建第二个查询获取特定
产品的结果相比)@Slyps这是真的。但这要追溯到应用程序设计。您需要的是一种将两个子表中的值与一个公共父表相结合的方法,并列出每个子表中的所有数据。上述解决方案可以做到这一点。根本问题的背景被省略了。该问题要求“列出每种产品,与价格所订购的产品类型无关,并在查询中包括产品表的具体信息”。上述方法当然与每个表的具体实现密切相关。@CJBS是的,我知道并同意。我并不是说你的回答不是对我问题的有效回答,我只是想输入我的想法来澄清我的问题,因为我可能已经描述了不清楚的部分。作为这个问题的未来读者的一个提示,可能会有一个想法。当然,如果在我放弃等待之前,你的答案仍然是唯一的,那么我显然会接受它,即使这不是我所希望的。我为你的努力感到抱歉,我应该说我在寻找一个sqlite解决方案,而不是仅仅标记它。OP表明他使用的是sqlite,而不是SQL Server。从所有答案来看,这似乎是一个需要最少的工作量和维护,同时提供想要的结果。+1这是一个更优雅的解决方案。当我没有返回到
products
表时,我最初沿着
UNION
路径,但忽略了价格排序。当需要对
price
进行排序时,显然将两个表连接回
products
更简单。定义视图以使用此查询的选项仍然适用。
DECLARE @SQL NVARCHAR(MAX) = 'CREATE VIEW vw_products_all AS ' +
    SUBSTRING((
        SELECT [text()] = REPLACE(REPLACE(REPLACE(
            ' UNION ALL {1}SELECT P.id, P.PRODUCT_ID, P.Name, {2} FROM dbo.products AS P INNER JOIN dbo.{0} AS PS ON P.PRODUCT_ID = PS.PRODUCT_ID'
            , '{0}', QUOTENAME(O.name))
            , '{1}', CHAR(10))
            , '{2}', SUBSTRING((
                SELECT [text()] = ', ' + ISNULL(QUOTENAME(C_this.name), 'NULL as ' + QUOTENAME(C_all.name))
                FROM sys.columns AS C_all
                    LEFT JOIN sys.columns AS C_this
                        ON O.object_id = C_this.object_id
                        AND C_all.name = C_this.name
                WHERE OBJECT_NAME(C_all.object_id) LIKE 'product[_]%'
                    AND c_all.name NOT IN ('PRODUCT_ID', 'ID')
                ORDER BY C_all.name
                FOR XML PATH('')
            ), 2, 10000000000000))
        FROM sys.objects AS O
        WHERE name LIKE 'product[_]%'
        FOR XML PATH('')
    ), 11, 1000000000000)

SELECT @SQL