1

我正在尝试编写一个可用于导出库存的视图。

我有两张桌子:

Inventory,其中包含列 Description、Year、Make、Model 和 Serial。

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

我想制作一个包含库存中所有列的视图,并为与序列号相关的 x 数量的图片添加列。

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

描述、年份、品牌、型号、序列号、DocumentBody1、MimeType1、Last Modified1、DocumentBody2、MimeType2、Last Modified2。

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

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

4

3 回答 3

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]

由于没有“分组依据”子句,这将为每张图片提供 1 行。然后你可以遍历结果。

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

于 2013-10-04T21:58:27.943 回答
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
于 2013-10-04T22:43:21.190 回答
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 合并。

于 2013-11-08T01:55:14.437 回答