我有一个这样的表格:
PID TIV_2011 TIV_2012 LAT LON
123 1000 1200 20.123489 80.341245
456 1500 3000 21.341287 80.341245
789 2000 1500 21.341287 80.341245
321 1000 750 21.123641 80.238716
567 1500 2300 22.123641 80.238716
问题:对于所有符合以下条件的投保人,编写一个查询以将2012年所有投资总值的总和打印为小数点后2位(TIV_2012):
具有与一个或多个其他保单持有人相同的TIV_2011值。
与另一个投保人不在同一个城市(即纬度,经度属性对必须唯一)。
我的查询
select cast(sum(i1.tiv_2012) as decimal(12,2))
from insurance i1 join insurance i2 on i1.tiv_2011 = i2.tiv_2011
where i1.pid != i2.pid
and i1.lat != i2.lat
and i1.lon != i2.lon
答案是7250,即1200 + 3000 + 750 + 2300。
但是实际答案应该是4250,即1200 + 750 + 2300
此问题已得到解答,可以正常运行的查询是:
select cast(sum(i1.tiv_2012) as decimal(12,2)) from insurance i1
join (select TIV_2011 from insurance group by TIV_2011 having count(*) > 1) i2 on i1.tiv_2011 = i2.TIV_2011
join (select lat,LON from insurance group by LAT,LON having COUNT(*) = 1) i3 on i1.LAT = i3.LAT and i1.LON = i3.LON
但是有人可以让我知道我的加入出现问题的原因或原因吗?
答案 0 :(得分:2)
更喜欢编写反映要求的更直接的SQL。如果要通过连接执行此操作,那么它会很快失去控制,因为连接将相互交叉相乘并增加行数。另外,两个带编号的子句要求使用不同的条件来表达,第二个子句仅对您希望失败的LEFT JOIN
起作用。
我希望使用两次EXISTS
检查:
declare @t table (PID int, TIV_2011 int, TIV_2012 int, Lat decimal(8,6),Lon decimal(9,6))
insert into @t(PID,TIV_2011,TIV_2012,LAT,LON) values
(123,1000,1200,20.123489,80.341245),
(456,1500,3000,21.341287,80.341245),
(789,2000,1500,21.341287,80.341245),
(321,1000, 750,21.123641,80.238716),
(567,1500,2300,22.123641,80.238716)
select
CONVERT(decimal(12,2),SUM(TIV_2012))
from
@t t_keep
where
exists (select * from @t t_other2011
where t_keep.PID != t_other2011.PID
and t_keep.TIV_2011 = t_other2011.TIV_2011
) and
not exists (select * from @t t_city
where t_keep.PID != t_city.PID and
t_keep.Lat = t_city.Lat and
t_keep.Lon = t_city.Lon)
从@t
(t_keep
)中选择行,其中(第一个EXISTS
)中表中的另一行针对另一个保单持有人,我们共享相同的TIV_2011
值。但也(and
,其中(第二EXISTS
)在表中的另一位保单持有人的行中不是 ,我们共享相同的Lat
和{{ 1}}值。
这将产生4250的值。
答案 1 :(得分:1)
您有两个独立的条件,但是尝试一起使用。例如,使用子查询将它们拆分出来,您将获得预期的结果。
DECLARE @Test TABLE (
PID int,
TIV_2011 int,
TIV_2012 int,
LAT DECIMAL(8,6),
LON DECIMAL(8,6)
)
INSERT @Test(PID, TIV_2011, TIV_2012, LAT, LON)
VALUES
(123, 1000, 1200, 20.123489, 80.341245),
(456, 1500, 3000, 21.341287, 80.341245),
(789, 2000, 1500, 21.341287, 80.341245),
(321, 1000, 750, 21.123641, 80.238716),
(567, 1500, 2300, 22.123641, 80.238716)
select cast(sum(i1.tiv_2012) as decimal(12,2))
from @Test i1
join @Test i2 on i1.tiv_2011 = i2.tiv_2011
AND i1.pid != i2.pid
where
NOT EXISTS (
SELECT 1
FROM @Test
WHERE LAT = i1.lat
and LON = i1.lon
AND PID != i1.pid
)
答案 2 :(得分:1)
这根本不是我要参加的任务。
Private Sub CommandButton1_Click()
Dim emptyRow As Long
'Validation
If WorksheetFunction.CountIf(Sheets("RawData").Range("A:A"),
Me.TextBox1.Value) = False Then
MsgBox "Ticket Does Not Exist", vbCritical
End If
'Determine emptyRow
emptyRow = WorksheetFunction.CountA(Range("A:A")) + 1
'Transfer information
With ThisWorkbook.Sheets("WOTracker")
.Cells(2, 1).EntireRow.Insert
.Cells(2, 1).Value = TextBox1.Value
.Cells(2, 5).Value = TextBox2.Value
.Cells(2, 2).Value = TextBox3.Value
.Cells(2, 3).Value = TextBox4.Value
.Cells(2, 6).Value = TextBox5.Value
.Cells(2, 7).Value = ComboBox1.Value
.Cells(2, 8).Value = ComboBox2.Value
.Cells(2, 9).Value = TextBox8.Value
.Cells(2, 4).Value = TextBox9.Value
End With
'Formatting
Dim dDate As Date
dDate = DateSerial(Month(Date), Day(Date), Year(Date))
TextBox2.Value = Format(TextBox2.Value, "mm/dd/yy")
dDate = TextBox2.Value
With ThisWorkbook.Sheets("WOTracker")
Sheets("WOTracker").Range("A2:Z2").Font.Bold = False
Sheets("WOTracker").Range("A2:Z2").Font.Underline = xlUnderlineStyleNone
End With
End Sub
我知道这不能回答您的问题,您的联接到底有什么问题。在我看来,这是只在表中查找其他行时甚至在这里使用联接的方法。对于查找记录,我们有select sum(tiv_2012)
from insurance i
where exists
(
select *
from mytable other
where other.pid <> i.pid
and other.tiv_2011 = i.tiv_2011
)
and not exists
(
select *
from mytable other
where other.pid <> i.pid
and other.lat = i.lat
and other.lon = i.lon
);
和EXISTS
,并且条件根据需要进入IN
子句。
答案 3 :(得分:0)
您的这一行是不同的,没有道理。
i1.pid != i2.pid
那不需要在那里。