簡體   English   中英

按列分組查詢結果(SQL Server)

[英]Query with grouped results by column (SQL Server)

我有一個許多人之間有很多關系items - itemnames - languages

itemnames不會出現在所有的語言。

我想得到一個只有一次表示的所有項目的結果,但是能夠將languageId設置為默認值。

例如,項目1,2,3以兩種語言定義,項目4和5各有一種語言,但語言不同

[itemid][languageid][name]
1,       1,         item1
1,       2,         leItem1
2,       1,         item2
2,       2,         leItem2
3,       1,         item3
3,       2,         leItem3
4,       1,         item4
5,       2,         leItem5

我想創建一個只給我一個itemID的查詢,但允許我指定哪個語言更喜歡 ,所以如果我選擇一個2的languageID ,我的查詢只會返回'leItem'的那個開頭的項目名稱除了第4項,它仍然應該給我item4

任何想法如何用SELECT實現這一點?

理論(我是如何讓它工作的)是,我創建了兩個查詢,一個用於languageID匹配x的所有查詢,第二個用於表示每個項目(按組或不同),然后合並結果。


用於生成表的sql

-- Languages
CREATE TABLE [Languages] (
    [id] INT NOT NULL PRIMARY KEY IDENTITY,
    [language] NVARCHAR(20) NOT NULL ,
    [languagecode] NVARCHAR(6) NOT NULL
);


-- Items
CREATE TABLE [Items] (
    [id] INT NOT NULL PRIMARY KEY IDENTITY,
    [ImageId] INT ,
    [lastupdate] DATETIME,
    [isactive] BIT NOT NULL DEFAULT 'TRUE'
);

-- ItemNames
CREATE TABLE [ItemNames] (
    [itemId] INT NOT NULL ,
    [languageId] INT NOT NULL ,
    [name] NVARCHAR(50) NOT NULL ,
    FOREIGN KEY (itemId) REFERENCES Items(id),
    FOREIGN KEY (languageId) REFERENCES Languages(id),
    PRIMARY KEY ([itemId],[languageId])
);

您可以使用子查詢來解決此問題。 這可能不是解決它的最佳方式,但我會采取措施。

SELECT DISTINCT
  outer.itemid, 
  outer.languageid, 
  outer.name 
FROM 
  table AS outer
WHERE 
  outer.languageid = 2  
  OR NOT EXIST (SELECT * FROM table AS inner WHERE languageid = 2 AND inner.itemid = outer.itemid)

第一個條件是提供屬於languageid = 2的所有條目,where條件的第二部分返回true,只有當你正在查看的當前項目沒有languageid = 2的條目時才返回true。

http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html

我會嘗試使用CASE語句。 基本思路是,以確定是否首選語言存在,返回null ,如果它沒有 這樣你就可以利用ISNULL返回首選語言(當它被填充時),否則返回最小語言ID:

// replace @preferred with the preferred language id ie 2
SELECT  itn.ItemID, itn.LanguageID, itn.Name
FROM    ItemNames itn INNER JOIN 
        (
            SELECT  itemID, 
                    // use preferred language if it exists
                    // otherwise, use the minimum languageID
                    ISNULL( MIN ( CASE WHEN LanguageID = @preferred THEN LanguageID ELSE NULL END ) 
                                , MIN (LanguageID) 
                          ) AS LanguageID
            FROM   ItemNames 
            GROUP BY itemID
        )
        sel ON sel.ItemID = itn.ItemID AND sel.LanguageID = itn.LanguageID 

這就是我現在處理它的方式......

我創建了一個循環遍歷查詢的cffunction。 它有效,因為我在查詢,我認為性能應該沒問題。 似乎使用數據庫端查詢對我來說可能太難了。

<cffunction name="getLanguageUniqueEntries" output="no" returntype="query" >
    <cfargument name="q" Type="query" required="true">
    <cfargument name="languageId" Type="string" required="true">
    <cfargument name="uniqueColumn" Type="string" required="false" default="ID">

    <!---  Copy structure, assume table has an id column where no item matches -1 --->
    <cfquery dbtype="query" name="newQ"> SELECT * FROM q WHERE #uniqueColumn# = -1 </cfquery>

    <!--- get list of unigue IDs --->
    <cfquery dbtype="query" name="uniquePropertyIDs"> SELECT #uniqueColumn# FROM q GROUP BY #uniqueColumn# </cfquery>

    <!--- loop through unique IDs ---->
    <cfloop query="uniquePropertyIDs">
        <cfset colIdVal = uniquePropertyIDs[uniqueColumn][uniquePropertyIDs.CurrentRow]>

        <!--- find row in language --->
        <cfquery dbtype="query" name="currentLangQ" maxrows="1">
            SELECT * FROM q WHERE #uniqueColumn# = #colIdVal# AND LanguageID = #languageId#
        </cfquery>

        <cfif currentLangQ.recordcount NEQ 0>
            <!--- insert row --->
            <cfquery dbtype="query" name="newQ"> SELECT * FROM newQ UNION SELECT * FROM currentLangQ </cfquery>
        <cfelse>
            <!--- entry in language not found, get a default value --->
            <cfquery dbtype="query" name="anyLangQ" maxrows="1"> SELECT * FROM q WHERE #uniqueColumn# = #colIdVal# ORDER BY LanguageID</cfquery>

            <!--- insert row --->
            <cfquery dbtype="query" name="newQ"> SELECT * FROM newQ UNION SELECT * FROM anyLangQ</cfquery>
        </cfif>

    </cfloop>
    <cfreturn newQ>
</cffunction>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM