2017-02-14 54 views
0

说我有三个表称为“用户”,“桥”和“卡”:从两张表中拉出所有数据,从第三行取出单行?

| ID | FirstName | LastName | 
|----|------------|----------| 
| 1 | David  | Gray  | 
| 2 | John  | Smith | 

| ID | CardNumber | 
|----|------------| 
| 1 | 101  | 
| 2 | 102  | 

| CardNumber | Value | 
|------------|-------| 
| 101  | ABC | 
| 101  | 1600 | 
| 101  | 1700 | 
| 101  | 1800 | 
| 102  | DEF | 
| 102  | 1699 | 
| 102  | 1799 | 
| 102  | 1899 | 

我想写一个查询,执行以下操作:

选择姓氏从表1,CardNumber从表2和价值从表3中,但我只想为每个用户单个最高(边注:我很高兴地抢CardNumber从卡,只要它相匹配)

所以我的查询将返回

David, Gray, 101, 1800 
John, Smith, 102, 1899 

但我不能工作,如何做,在MS-SQL。这是我到目前为止:

SELECT 
Users.ID, 
Users.FirstName, 
Users.LastName, 
Bridge.CardNumber, 
Cards.Value 
FROM Users 
LEFT JOIN Bridge ON Users.ID = Bridge.ID 
LEFT JOIN Cards ON Bridge.CardNumber = Cards.CardNumber 
WHERE 
Cards.Value = (SELECT Cards.Value FROM Cards ORDER BY Cards.Value DESC) 

返回单个用户,而不是所有用户。删除WHERE子句会按照我的预期返回所有用户,但我不确定如何取得中间立场。

我创建了一个SQLite fiddle here,这是非常接近(我可以从那里转口味)

我可以在这里做什么?

+0

是值可以是ABC?防守? –

+0

@ShakeerMirza:不需要,它需要是一个数字,因为结果最终打印在只接受数字的磁条上 – Grayda

回答

0

试试这个:

select t.* 
from (
    select Users.ID, 
     Users.FirstName, 
     Users.LastName, 
     Bridge.CardNumber, 
     Cards.Value, 
     row_number() over (
      partition by Users.id order by convert(int, Cards.value) desc 
      ) rn 
    from Users 
    left join Bridge on Users.ID = Bridge.ID 
    left join Cards on Bridge.CardNumber = Cards.CardNumber 
     and Cards.Value not like '%[^0-9]%' 
    ) t 
where rn = 1; 
0

就拿MAX(value)和留在Group BY

模式:

CREATE TABLE #USERS(ID INT,FirstName VARCHAR(50),LastName VARCHAR(50)) 
INSERT INTO #USERS 
SELECT 1, 'David' ,  'Gray' 
UNION ALL 
SELECT 2, 'John' ,  'Smith'  

CREATE TABLE #BRIDGE(ID INT, CardNumber VARCHAR(50)) 
INSERT INTO #BRIDGE 

SELECT 1 , 101   
UNION ALL 
SELECT 2 , 102   

CREATE TABLE #CARDS(CardNumber VARCHAR(50), Value INT) 

INSERT INTO #CARDS 
SELECT 101,   '1000' 
UNION ALL 
SELECT 101 ,  '1600' 
UNION ALL 
SELECT 101 ,  '1700' 
UNION ALL 
SELECT 101 ,  '1800' 
UNION ALL 
SELECT 102 ,  '800' 
UNION ALL 
SELECT 102 ,  '1699' 
UNION ALL 
SELECT 102 ,  '1799' 
UNION ALL 
SELECT 102 ,  '1899' 

%的评论

不行,它需要一个数字,

SELECT U.FirstName, U.LastName, B.CardNumber,MAX(C.Value) 
FROM #USERS U 
INNER JOIN #BRIDGE B ON U.ID = B.ID 
INNER JOIN #CARDS C ON B.CardNumber = C.CardNumber 
GROUP BY U.FirstName, U.LastName, B.CardNumber 

如果该值是varchar类型的,并且具有像美国广播公司的价值观和要排除他们..

SELECT U.FirstName, U.LastName, B.CardNumber,MAX(CAST(C.Value AS INT) ) 
FROM #USERS U 
INNER JOIN #BRIDGE B ON U.ID = B.ID 
INNER JOIN #CARDS C ON B.CardNumber = C.CardNumber 
WHERE ISNUMERIC(Value)=1 
GROUP BY U.FirstName, U.LastName, B.CardNumber 

而结果将是

+-----------+----------+------------+-------+ 
| FirstName | LastName | CardNumber | value | 
+-----------+----------+------------+-------+ 
| David  | Gray  |  101 | 1800 | 
| John  | Smith |  102 | 1899 | 
+-----------+----------+------------+-------+ 
1

选中此项。 使用group by和max()函数的简单解决方案。

SELECT 
    Users.ID, 
    Users.FirstName, 
    Users.LastName, 
    Bridge.CardNumber, 
    MAX(cast(Cards.Value as int)) 
    FROM Users 
    LEFT JOIN Bridge ON Users.ID = Bridge.Id 
    LEFT JOIN Cards ON Bridge.CardNumber = Cards.CardNumber 
    GROUP BY 
    Users.ID, 
    Users.FirstName, 
    Users.LastName, 
    Bridge.CardNumber 

SQLite fiddle here,

1

尝试......

select t1.ID,t1.FirstName,t1.LastName,t2.CardNumber, 
max(cast(t3.Value as int)) as [MaxValue] 
from tblUsers t1 
inner join tblBridge t2 on t1.ID=t2.ID 
inner join tblCards t3 on t2.CardNumber=t3.CardNumber 
where isnumeric(t3.Value)=1  
group by t1.ID,t1.FirstName,t1.LastName,t2.CardNumber 

怎么一回事,因为连接查询计算从卡表最大值与查询绑定的每个itteration。使用

+0

现在我的查询已更新为“where isnumeric(t3.Value)= 1”,用于检查“101 | ABC“ –

0

简单的子查询,我们可以通过这种方式也

select 
T.FirstName, 
T.LastName, 
TT.CardNumber, 
TTT.Value 
    from users T 
INNER JOIN Bridge TT 
ON T.ID = TT.ID 
INNER JOIN (Select MAX(Value) Value , 
       CardNumber 
          from Cards 
           WHERE CardNumber = CardNumber 
AND VALUE LIKE '%[^A-Za-z]%' 
GROUP BY CardNumber) TTT 
ON TT.CardNumber = TTT.CardNumber 
0

使用LEFT JOIN做。并根据Value列给出Cards表的行号。

查询

select t1.FirstName, t1.LastName, t2.CardNumber, t3.Value 
from Users t1 
left join Bridge t2 
on t1.ID = t2.ID 
left join (
    select [rn] = row_number() over(
     partition by CardNumber 
     order by case when Value like '[0-9]%' then 1 else 2 end, 
     len(Value) desc, Value desc 
    ), * from Cards) t3 
on t2.CardNumber = t3.CardNumber 
and t3.[rn] = 1; 
相关问题