【问题标题】:Populating NULLS from LEFT JOIN with values用值填充 LEFT JOIN 中的 NULLS
【发布时间】:2013-01-21 20:59:13
【问题描述】:
SELECT

    rates_Calendar.date,
    subQuery.name,
    COALESCE(subQuery.amount,0) as amount,
    subQuery.reference,
    subQuery.property


FROM
    rates_Calendar
    LEFT JOIN (
                SELECT
                    rates_Booking.date,
                    unit.unit,
                    unit.abbreviation as name,
                    rates_Booking.amount,
                    rates_Booking.bookingReference AS reference,
                    property.property


                FROM
                    rates_Booking

                    LEFT JOIN booking ON booking.reference = rates_Booking.bookingReference

                    LEFT JOIN unit ON booking.apartment = unit.unit

                    LEFT JOIN property ON property.property = unit.property

                    # unit to apartments
                    LEFT JOIN apartments ON (apartments.unit = unit.unit)
                    LEFT JOIN apartmentTypes ON (apartmentTypes.id = apartments.apartmentTypeId)

                WHERE
                    rates_Booking.date BETWEEN @startDate AND @endDate
                    AND unit.unit = 221



                GROUP BY
                    property.area,
                    property.property,
                    apartmentTypes.id,
                    unit.unit,
                    rates_Booking.date

                ) AS subQuery ON subQuery.date = rates_Calendar.date


 WHERE
     rates_Calendar.date BETWEEN @startDate AND @endDate
 GROUP BY 
subQuery.reference,
subQuery.unit,
subQuery.apartmentTypeId,
subQuery.property,
subQuery.area,
    rates_Calendar.date

现在,显然这个查询将导致不匹配的日期为 NULLS。 有没有办法用 NON NULL 值更新所有 NULLS?

2013-01-01  unitA 138 1      property1
2013-01-02  unitA 138 1      property1
2013-01-03  unitA 138 1      property1
2013-01-04  NULL  0   NULL   NULL
2013-01-05  NULL  0   NULL   NULL

有没有办法用相应列中的非空值更新空值?

我正在尝试这样做,因为从链接中可以理解,用 NULLS 隐藏 rowGroups 是不可能的: Hide NULL Row Groups JasperReports

【问题讨论】:

    标签: mysql sql database group-by left-join


    【解决方案1】:

    我认为您不想要LEFT JOIN 然后使用您的subQuery。试试这个:

    SELECT
    
        rates_Calendar.date,
        subQuery.name,
        COALESCE(subQuery.amount,0) as amount,
        subQuery.reference,
        subQuery.property
    
    
    FROM
        rates_Calendar, (
                    SELECT
                        rates_Booking.date,
                        unit.unit,
                        unit.abbreviation as name,
                        rates_Booking.amount,
                        rates_Booking.bookingReference AS reference,
                        property.property
    
    
                    FROM
                        rates_Booking
    
                        LEFT JOIN booking ON booking.reference = rates_Booking.bookingReference
    
                        LEFT JOIN unit ON booking.apartment = unit.unit
    
                        LEFT JOIN property ON property.property = unit.property
    
                        # unit to apartments
                        LEFT JOIN apartments ON (apartments.unit = unit.unit)
                        LEFT JOIN apartmentTypes ON (apartmentTypes.id = apartments.apartmentTypeId)
    
                    WHERE
                        rates_Booking.date BETWEEN @startDate AND @endDate
                        AND unit.unit = 221
    
    
    
                    GROUP BY
                        property.area,
                        property.property,
                        apartmentTypes.id,
                        unit.unit,
                        rates_Booking.date
    
                    ) AS subQuery
    
    
     WHERE
       rates_Calendar.date BETWEEN @startDate AND @endDate
    

    【讨论】:

    • IFNULL 可能可以使用,但我怎样才能使用上述行中的 NON NULL 值更新 NULLS?
    • 至于您的其他评论,我已经完全修改了我的答案。 :-)
    • 首先,查询生成重复行。我可以使用 Group By rates_Calendar.date 来消除这些。但我确实希望金额与我原来的帖子中的一样。但您的建议将所有值更新为 138。
    • 对。您可以使用我建议的 subQuery 并将其命名为 subQuery2 并将其添加到您拥有的一个子查询中。然后一开始你可以使用subQuery2,除了带有138/0的那个。不要忘记GROUP BY
    • 这适用于单元级别(我的意思是 unit.unit=221)。但是,当您将其更改为属性级别 (property.area = 'London') 时,所有金额都保持不变。我有一个带有子查询的 LEFT JOIN,用于金额,第二个子查询用于其余字段。
    【解决方案2】:

    这是你想要的吗?

    SELECT rates_Calendar.date, coalesce(subQuery.name, 'unitA'),
            COALESCE(subQuery.amount,0) as amount,
            coalesce(subQuery.reference, 1),
            coalesce(subQuery.property, 'property1')
    . . .
    

    或者,您是否想从列中读取值,例如:

    select rates_Calendar.date,
           coalesce(subquery.Name, max(SubQuery.name) over ()) as name,
           COALESCE(subQuery.amount,0) as amount,
           coalesce(subQuery.reference, max(subquery.reference) over ()) as reference,
           coalesce(subQuery.property, max(subquery.property) over ()) as property
    

    这会从列中获取最大值并将其用作默认值。

    【讨论】:

    • 嗨,戈登,我不是这个意思。希望你已经看到了上面的对话。
    • @Ravi 。 . .实际上,在我看来,第二个查询 确实 回答了您的问题。和你想要的有什么不同?
    • 第二个查询将回答我的问题,如果它没有获取 NULL 作为最大值。这没用。它不会选择列的最大值。 SELECT rates_Calendar.date, COALESCE(subQuery.id,max(subQuery.id)), COALESCE(subQuery.region,max(subQuery.region)), COALESCE(subQuery.building,max(subQuery.building)), COALESCE(subQuery .title,max(subQuery.title)), COALESCE(subQuery.name,max(subQuery.name)), COALESCE(subQuery.amount,max(subQuery.amount))
    • @Ravi 。 . .获取 NULL 作为最大值的唯一方法是当所有值都为 NULL 时。在这种情况下,您无需填写任何内容。
    • @Ravi 。 . .是的,这与分组有关。在这种情况下,语法会有所不同。
    【解决方案3】:

    你可能需要 IFNULL 函数吗?

    select ifnull(some_field, 'default_value') from mytable
    

    【讨论】:

    • 在上述情况下,没有什么比默认值更好的了。它需要在整个第二列中为unitA,在整个第4列中为1,在整个第5列中为property1。
    【解决方案4】:

    我设法通过使用 CROSS JOIN ON rates_Calendar 和单位表并在这两个表上加入子查询来做到这一点。

    【讨论】:

      猜你喜欢
      • 2020-08-09
      • 1970-01-01
      • 1970-01-01
      • 2010-09-29
      • 1970-01-01
      • 2011-10-13
      • 2020-10-11
      • 1970-01-01
      相关资源
      最近更新 更多