SQL Server - 尝试对我的表进行反规范化

时间:2017-08-28 13:20:48

标签: sql sql-server join

为标题道歉,但我试图在我的水平之上做一些事情,甚至让我解释它。

假设我有一个包含变量person,foodstuff和amount的表:

Person  Butter Milk Chicken
Mike    3      4    2

通过在查询中加入表格本身,我设法制作了一个列表,其中食物是新变量的基础,值是金额。上表将成为:

Select 
    a.person, 
    b.amount as Butter,
    c.amount as Milk, 
    d.amount as Chicken
from PersonFoodAmount a
inner join PersonFoodAmount b on a.person = b.person
inner join PersonFoodAmount c on a.person=c.person
where b.food='Butter' 
and c.food='Milk'
and d.food='Chicken'

代码大约是:

Person  Butter Milk Chicken
Mike    3      4    2
Tim     NULL   4    NULL
John    NULL   Null 2

现在,这给了我Mike,因为他检查了所有的盒子。但我还需要部分匹配:

protected override bool AuthorizeCore(HttpContextBase httpContext)
        {


            if (false)//Here is custom logic that is working
            {
                string message = "You don't have an access to selected menu item.";
                var dataDict = HttpContext.Current.Session["__ControllerTempData"] as IDictionary<string, object>;
                if (dataDict == null)
                {
                    Dictionary<string, object> dictionary = new Dictionary<string, object>();
                    dictionary["myErrorMessage"] = message;
                    HttpContext.Current.Session["__ControllerTempData"] = dictionary;
                }
                else
                {
                    dataDict["myErrorMessage"] = message;
                    HttpContext.Current.Session["__ControllerTempData"] = dataDict;
                }

                _isAuthorized = false;

                httpContext.Response.Redirect("Home");                
            }
            else
            {
                _isAuthorized = base.AuthorizeCore(httpContext);
            }

            return _isAuthorized;
        }

我尝试过各种各样的连接,包括全外连接,但我仍然只能找到装满冰箱的人。

有什么建议吗?

2 个答案:

答案 0 :(得分:6)

您可以使用Pivot进行此操作。

DECLARE @PersonStuff TABLE (Person varchar(10), Food varchar(10), Amount INT)

INSERT INTO @PersonStuff VALUES
('Mike','Butter', 3),
('Mike','Milk', 4),
('Mike','Chicken', 2),
('Tim','Milk', 4),
('John','Chicken', 2)

SELECT 
    * 
FROM ( 
    SELECT 
        * 
    FROM @PersonStuff ) AS SourceTable
PIVOT ( 
    AVG(Amount) 
    FOR Food IN ( [Butter],[Milk],[Chicken] ) 
) AS PivotTable

结果:

Person  Butter  Milk    Chicken
John    NULL    NULL    2
Mike    3       4       2
Tim     NULL    4       NULL

答案 1 :(得分:5)

我会建议更好的条件聚合:

SELECT t.person,
       MAX(CASE WHEN t.food = 'Butter' THEN t.amout END) as Butter,
       MAX(CASE WHEN t.food = 'Milk' THEN t.amout END) as Milk,
       MAX(CASE WHEN t.food = 'Chicken' THEN t.amout END) as Chicken
FROM PersonFoodAmount t
GROUP BY t.person

这样,您不必将表连接3次。此外,我发现这篇文章更容易阅读一次以理解它。