SQL连接表;你能重复一下吗?

时间:2013-10-04 21:36:02

标签: sql-server database-design join

我正在尝试撰写一个我们可以用来导出库存的视图。

我有两张桌子:

广告资源,其中包含Description,Year,Make,Model和Serial列。

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

我想创建一个包含Inventory中所有列的视图,并添加与序列号相关的x个图片的列。

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

Description,Year,Make,Model,Serial,DocumentBody1,MimeType1,Last Modified1,DocumentBody2,MimeType2,Last Modified2。

对于那些只有一张图片的库存商品,第二张图片列都将为空。

这是我甚至可以做的事情吗?从我正在阅读的关于连接的内容来看,它似乎不可能。

3 个答案:

答案 0 :(得分:2)

Select inventory.*, count(pictures.serial) as picture_count From inventory Left Join pictures On inventory.serial = pictures.serial Where [your where statement]

如果根本没有照片,请使用Left Join。这样你仍然可以得到一个结果。

<强>更新

实际上,在再次阅读您的问题后,您似乎只想用系统中的每张附加图片扩展您的搜索结果。这不是最好的方法。您可以做的最好的事情就是为系统中的每张图片返回一行。

Select inventory.*, pictures.DocumentBody, pictures.MimeType, pictures.Serial, pictures.Last_Modified From inventory Left Join pictures On inventory.serial = pictures.serial Where [your where statement]

由于没有“Group By”子句,这将为每张图片提供1行。然后你可以循环搜索结果。

同时

有一些方法可以通过创建临时表,在存储过程中循环结果,为每个图片结果创建新列(DocumentBody1,DocumentBody2等)并将数据添加到新字段,然后查询临时表来实现此目的。 。但是,我认为这是很多事情。

答案 1 :(得分:2)

正如其他人所说,您应该评估您是否确实需要您认为需要的视图。但如果你真的想要它,你可以在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

答案 2 :(得分:0)

感谢大家的帮助。最后,我最终使用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);
?>

这会将文件输出,但我仍然需要将生成的CSV与主“信息”CSV合并。