Sql server SQL连接表;你能重复几列吗?

Sql server SQL连接表;你能重复几列吗?,sql-server,database-design,join,Sql Server,Database Design,Join,我正在尝试组成一个视图,我们可以使用它导出我们的库存 我有两张桌子: 库存,包含描述、年份、品牌、型号和序列列 图片,其中包含DocumentBody、MimeType、Serial和Last Modified列 我想创建一个视图,其中包含库存中的所有列,还添加了与序列号相关的x数量图片的列 因此,如果有两张图片具有相同的序列号,则结果表将包括以下字段: 说明、年份、品牌、型号、序列、DocumentBody1、MimeType1、上次修改1、DocumentBody2、MimeType2、上次

我正在尝试组成一个视图,我们可以使用它导出我们的库存

我有两张桌子:

库存,包含描述、年份、品牌、型号和序列列

图片,其中包含DocumentBody、MimeType、Serial和Last Modified列

我想创建一个视图,其中包含库存中的所有列,还添加了与序列号相关的x数量图片的列

因此,如果有两张图片具有相同的序列号,则结果表将包括以下字段:

说明、年份、品牌、型号、序列、DocumentBody1、MimeType1、上次修改1、DocumentBody2、MimeType2、上次修改2

对于只有一张图片的库存项目,第二张图片列将全部为空


这是我能做的吗?从我所读到的关于连接的内容来看,这似乎是不可能的。

选择inventory.*,将(pictures.serial)计数为picture\u从inventory上的左侧连接pictures.serial=pictures.serial Where[您的Where语句]

如果根本没有图片,请使用左连接。这样你仍然可以得到一个结果

更新

实际上,在再次阅读您的问题之后,您似乎只想通过系统中的每一张附加图片来扩展搜索结果。这不是最好的办法。您所能做的最好的事情就是为系统中的每个pic返回一行

选择inventory.*、pictures.DocumentBody、pictures.MimeType、pictures.Serial、pictures.Last\u从库存左侧修改加入inventory.Serial=pictures.Serial Where[您的Where语句]

由于没有“GROUPBY”子句,这将为每张图片提供1行。然后,您可以循环查看结果

同时


有几种方法可以做到这一点:制作临时表,在存储过程中循环结果,为每个图片结果创建新列(DocumentBody1、DocumentBody2等),并将数据添加到新字段,然后查询临时表。但我认为这需要做很多工作。

选择库存。*,将(pictures.serial)计数为库存中的picture\u从库存左侧加入inventory.serial=pictures.serial Where[您的Where语句]

如果根本没有图片,请使用左连接。这样你仍然可以得到一个结果

更新

实际上,在再次阅读您的问题之后,您似乎只想通过系统中的每一张附加图片来扩展搜索结果。这不是最好的办法。您所能做的最好的事情就是为系统中的每个pic返回一行

选择inventory.*、pictures.DocumentBody、pictures.MimeType、pictures.Serial、pictures.Last\u从库存左侧修改加入inventory.Serial=pictures.Serial Where[您的Where语句]

由于没有“GROUPBY”子句,这将为每张图片提供1行。然后,您可以循环查看结果

同时


有几种方法可以做到这一点:制作临时表,在存储过程中循环结果,为每个图片结果创建新列(DocumentBody1、DocumentBody2等),并将数据添加到新字段,然后查询临时表。但我认为这需要经历很多。

正如其他人所说,您可能应该评估是否确实需要您认为需要的视图。但如果您确实需要,可以在MSSQL中使用PIVOT:

WITH BaseData AS
(
    SELECT Serial
        ,DocumentBody
        ,MimeType
        ,LastModified
        ,ROWNUMBER() OVER(PARTITION BY Serial ORDER BY LastModified) AS RowNum
    FROM Pictures) AS t
),
DocumentPivot AS (
    SELECT 
        Serial
        ,DocumentBody
        ,'DocumentBody' + RowNum AS ColumnName
    FROM BaseData
),
MimePivot AS (
    SELECT 
        Serial
        ,MimeType
        ,'MimeType' + RowNum AS ColumnName
    FROM BaseData
),
ModifiedPivot AS (
    SELECT 
        Serial
        ,LastModified
        ,'LastModified' + RowNum AS ColumnName
    FROM BaseData
)
SELECT Description
    ,Year
    ,Make
    ,Model
    ,Inventory.Serial
    ,DocumentBody1
    ,MimeType1
    ,LastModified1
    ,DocumentBody2
    ,MimeType2
    ,LastModified2
    ,...
    ,LastModified10
FROM Inventory
    LEFT OUTER JOIN (
        SELECT Serial
            ,DocumentBody1
            ,DocumentBody2
            ,...
            ,DocumentBody10
        FROM DocumentPivot
            PIVOT (MAX(DocumentBody) FOR ColumnName IN (DocumentBody1, DocumentBody2, ..., DocumentBody10)) AS P1
    ) AS Documents
        ON Documents.Serial=Inventory.Serial
    LEFT OUTER JOIN (
        SELECT Serial
            ,MimeType1
            ,MimeType2
            ,...
            ,MimeType10
        FROM MimePivot
            PIVOT (MAX(MimeType) FOR ColumnName IN (MimeType1, MimeType2, ..., MimeType10)) AS P2
    ) AS Mimes
        ON Mimes.Serial=Inventory.Serial
    LEFT OUTER JOIN (
        SELECT Serial
            ,LastModified1
            ,LastModified2
            ,...
            ,LastModified10
        FROM ModifiedPivot
            PIVOT (MAX(LastModified) FOR ColumnName IN (LastModified1, LastModified2, ..., LastModified10)) AS P3
    ) AS Modifieds
        ON Modifieds.Serial=Inventory.Serial

正如其他人所说,您可能应该评估是否确实需要您认为需要的视图。但如果您确实需要,可以在MSSQL中使用PIVOT:

WITH BaseData AS
(
    SELECT Serial
        ,DocumentBody
        ,MimeType
        ,LastModified
        ,ROWNUMBER() OVER(PARTITION BY Serial ORDER BY LastModified) AS RowNum
    FROM Pictures) AS t
),
DocumentPivot AS (
    SELECT 
        Serial
        ,DocumentBody
        ,'DocumentBody' + RowNum AS ColumnName
    FROM BaseData
),
MimePivot AS (
    SELECT 
        Serial
        ,MimeType
        ,'MimeType' + RowNum AS ColumnName
    FROM BaseData
),
ModifiedPivot AS (
    SELECT 
        Serial
        ,LastModified
        ,'LastModified' + RowNum AS ColumnName
    FROM BaseData
)
SELECT Description
    ,Year
    ,Make
    ,Model
    ,Inventory.Serial
    ,DocumentBody1
    ,MimeType1
    ,LastModified1
    ,DocumentBody2
    ,MimeType2
    ,LastModified2
    ,...
    ,LastModified10
FROM Inventory
    LEFT OUTER JOIN (
        SELECT Serial
            ,DocumentBody1
            ,DocumentBody2
            ,...
            ,DocumentBody10
        FROM DocumentPivot
            PIVOT (MAX(DocumentBody) FOR ColumnName IN (DocumentBody1, DocumentBody2, ..., DocumentBody10)) AS P1
    ) AS Documents
        ON Documents.Serial=Inventory.Serial
    LEFT OUTER JOIN (
        SELECT Serial
            ,MimeType1
            ,MimeType2
            ,...
            ,MimeType10
        FROM MimePivot
            PIVOT (MAX(MimeType) FOR ColumnName IN (MimeType1, MimeType2, ..., MimeType10)) AS P2
    ) AS Mimes
        ON Mimes.Serial=Inventory.Serial
    LEFT OUTER JOIN (
        SELECT Serial
            ,LastModified1
            ,LastModified2
            ,...
            ,LastModified10
        FROM ModifiedPivot
            PIVOT (MAX(LastModified) FOR ColumnName IN (LastModified1, LastModified2, ..., LastModified10)) AS P3
    ) AS Modifieds
        ON Modifieds.Serial=Inventory.Serial

谢谢大家的帮助。最后,我使用PHP完成了以下代码:

<?php
date_default_timezone_set('America/Edmonton');

$serverName = "database";
$connectionInfo = array( "Database"=>"CRM_MSCRM");
$conn = sqlsrv_connect( $serverName, $connectionInfo);

if( $conn === false )
    {
        echo "Unable to connect.\n\n";
        die( print_r( sqlsrv_errors(), true));
    }
else
    {
        echo "Connected. Selecting trucks...\n\n";
    }

$tsql = "SELECT * FROM CRM_MSCRM.dbo.Trader_Export_Simple";
$stmt = sqlsrv_query( $conn, $tsql);

if( $stmt === false )
    {
        echo "Error executing query.\n\n";
        die( print_r( sqlsrv_errors(), true));
    }

$csvData = array();

while ($row = sqlsrv_fetch_array($stmt))
    {
        $count = 1;
        $mainpicsql = "SELECT * FROM CRM_MSCRM.dbo.TruckImages WHERE Serial = '".$row[0]."' AND MainPic = 1";
        $mainpicstmt = sqlsrv_query( $conn, $mainpicsql);
        while ($mainpicrow = sqlsrv_fetch_array($mainpicstmt))
            {
                $truck = $mainpicrow[1];
                $mainfilename = $truck ."-". $count . ".png";
                file_put_contents($mainfilename, base64_decode($mainpicrow[0]));
                $mainpicdate = $mainpicrow[3]->format("d/m/Y h:m:s");
                $mainfilename = "http://images.website/images/".$mainfilename;
                echo $mainpicdate."\n";
            }

        $picsql = "SELECT * FROM CRM_MSCRM.dbo.TruckImages WHERE Serial = '".$row[0]."' AND MainPic = 0";
        $picstmt = sqlsrv_query( $conn, $picsql);
        $extrapicsdate = "";
        $filenames = "";

        while ($picrow = sqlsrv_fetch_array($picstmt))
            {
                $count++;
                $filename = $picrow[1] ."-". $count . ".png";
                file_put_contents($filename, base64_decode($picrow[0]));
                $picdate = $picrow[3]->format("d/m/Y h:m:s");
                $filenames .= "http://images.website/images/".$filename.";";
                $extrapicsdate .= $picdate.";";
            }

        $filenames = rtrim($filenames, ";");
        $extrapicsdate = rtrim($extrapicsdate, ";");
        echo $filenames."\n";
        echo $extrapicsdate."\n";
        if ($truck != "") {
            $csvData[] = array($truck, $mainfilename, $mainpicdate, $filenames, $extrapicsdate);
        }

        if ($filenames != "")
            {
                $filenames = "";
            }        
        if ($extrapicsdate != "")
            {
                $extrapicsdate = "";
            }

        echo "Next truck...\n\n";
        $truck = "";
        $mainfilename = "";
        $mainpicdate = "";
    }
    $fp = fopen('file.csv', 'w');
    foreach ($csvData as $fields) {
        fputcsv($fp, $fields);
    }
    //print_r($csvData);
sqlsrv_free_stmt( $stmt);
sqlsrv_free_stmt( $picstmt);
sqlsrv_close( $conn);
?>

谢谢大家的帮助。最后,我使用PHP完成了以下代码:

<?php
date_default_timezone_set('America/Edmonton');

$serverName = "database";
$connectionInfo = array( "Database"=>"CRM_MSCRM");
$conn = sqlsrv_connect( $serverName, $connectionInfo);

if( $conn === false )
    {
        echo "Unable to connect.\n\n";
        die( print_r( sqlsrv_errors(), true));
    }
else
    {
        echo "Connected. Selecting trucks...\n\n";
    }

$tsql = "SELECT * FROM CRM_MSCRM.dbo.Trader_Export_Simple";
$stmt = sqlsrv_query( $conn, $tsql);

if( $stmt === false )
    {
        echo "Error executing query.\n\n";
        die( print_r( sqlsrv_errors(), true));
    }

$csvData = array();

while ($row = sqlsrv_fetch_array($stmt))
    {
        $count = 1;
        $mainpicsql = "SELECT * FROM CRM_MSCRM.dbo.TruckImages WHERE Serial = '".$row[0]."' AND MainPic = 1";
        $mainpicstmt = sqlsrv_query( $conn, $mainpicsql);
        while ($mainpicrow = sqlsrv_fetch_array($mainpicstmt))
            {
                $truck = $mainpicrow[1];
                $mainfilename = $truck ."-". $count . ".png";
                file_put_contents($mainfilename, base64_decode($mainpicrow[0]));
                $mainpicdate = $mainpicrow[3]->format("d/m/Y h:m:s");
                $mainfilename = "http://images.website/images/".$mainfilename;
                echo $mainpicdate."\n";
            }

        $picsql = "SELECT * FROM CRM_MSCRM.dbo.TruckImages WHERE Serial = '".$row[0]."' AND MainPic = 0";
        $picstmt = sqlsrv_query( $conn, $picsql);
        $extrapicsdate = "";
        $filenames = "";

        while ($picrow = sqlsrv_fetch_array($picstmt))
            {
                $count++;
                $filename = $picrow[1] ."-". $count . ".png";
                file_put_contents($filename, base64_decode($picrow[0]));
                $picdate = $picrow[3]->format("d/m/Y h:m:s");
                $filenames .= "http://images.website/images/".$filename.";";
                $extrapicsdate .= $picdate.";";
            }

        $filenames = rtrim($filenames, ";");
        $extrapicsdate = rtrim($extrapicsdate, ";");
        echo $filenames."\n";
        echo $extrapicsdate."\n";
        if ($truck != "") {
            $csvData[] = array($truck, $mainfilename, $mainpicdate, $filenames, $extrapicsdate);
        }

        if ($filenames != "")
            {
                $filenames = "";
            }        
        if ($extrapicsdate != "")
            {
                $extrapicsdate = "";
            }

        echo "Next truck...\n\n";
        $truck = "";
        $mainfilename = "";
        $mainpicdate = "";
    }
    $fp = fopen('file.csv', 'w');
    foreach ($csvData as $fields) {
        fputcsv($fp, $fields);
    }
    //print_r($csvData);
sqlsrv_free_stmt( $stmt);
sqlsrv_free_stmt( $picstmt);
sqlsrv_close( $conn);
?>

如果您不知道每个
库存的
图片数
提前记录,您可能应该重新考虑您的设计。表应该有
n
行,而不是列。为什么需要这样做?每个库存项目最多有十张图片。然而,可能只有一张图片或零张图片上传。所以我知道这些限制。我需要能够做到这一点,因为我正在尝试导出所有要上传到另一个网站的图像。计划是,如果我能够获得正确的视图,那么我可以提取每个DocumentBody,并根据MimeType将其保存为适当的文件,然后用新创建的文件的URL替换DocumentBody。这就是我的希望。。。。SQL真是太让我头疼了。
每个库存项目最多有十张图片
-这些类型的规则往往会随着时间的推移而变化,最好为n张图片设计,让软件级别的业务规则强制执行。。。如果有必要的话。不要只考虑今天的因素进行设计,它可能会在#$$之后咬到你……如果你不知道每个
库存
提前记录的
图片的数量,你可能应该重新考虑你的设计。表应该有
n
行,而不是列。为什么需要这样做?每个库存项目最多有十张图片。然而,可能只有一张图片或零张图片上传。所以我知道这些限制。我需要能够做到这一点,因为我正在尝试导出所有要上传到另一个网站的图像。计划是,如果我能够获得正确的视图,那么我可以提取每个DocumentBody,并根据MimeType将其保存为适当的文件,然后用新创建的文件的URL替换DocumentBody。这就是我的希望。。。。SQL真是让我难以理解。
每个发明最多有十张图片