当我在表格上有多个连接后运行一个select时,我有一个2列的输出,我想为返回的行集选择col1和col2的不同组合。
我运行的查询将是这样的:
select a.Col1,b.Col2 from a inner join b on b.Col4=a.Col3
现在输出有点像这样
Col1 Col2
1 z
2 z
2 x
2 y
3 x
3 x
3 y
4 a
4 b
5 b
5 b
6 c
6 c
6 d
现在我希望输出应该像下面这样
1 z
2 y
3 x
4 a
5 b
6 d
如果我随机选择第二列就可以了,因为我的查询输出就像一百万行而且我真的认为有一种情况我会让Col1和Col2输出相同,即使这样我也可以编辑值..
你能帮我一样吗...我认为基本上col3需要是一个行号我猜,然后我需要在随机行号上选择两个cols基地..我不知道我怎么转这个到SQL
考虑案例1a 1b 1c 1d 1e 2a 2b 2c 2d 2e现在group by将给出所有这些结果,其中我想要1a和2d或1a和2b。任何这样的组合。
好的,让我解释一下我的期望:
with rs as(
select a.Col1,b.Col2,rownumber() as rowNumber from a inner join b on b.Col4=a.Col3)
select rs.Col1,rs.Col2 from rs where rs.rowNumber=Round( Rand() *100)
现在我不知道如何让rownumber或随机工作正常!!
提前致谢。
答案 0 :(得分:6)
如果您根本不关心返回col2
值
select a.Col1,MAX(b.Col2) AS Col2
from a inner join b on b.Col4=a.Col3
GROUP BY a.Col1
如果您确实需要随机值,可以使用以下方法。
;WITH T
AS (SELECT a.Col1,
b.Col2
ROW_NUMBER() OVER (PARTITION BY a.Col1 ORDER BY (SELECT NEWID())
) AS RN
FROM a
INNER JOIN b
ON b.Col4 = a.Col3)
SELECT Col1,
Col2
FROM T
WHERE RN = 1
或者使用CLR Aggregate函数。这种方法的优点在于它消除了按partition, newid()
排序的要求,下面是一个示例实现。
using System;
using System.Data.SqlTypes;
using System.IO;
using System.Security.Cryptography;
using Microsoft.SqlServer.Server;
[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize = 8000)]
public struct Random : IBinarySerialize
{
private MaxSoFar _maxSoFar;
public void Init()
{
}
public void Accumulate(SqlString value)
{
int rnd = GetRandom();
if (!_maxSoFar.Initialised || (rnd > _maxSoFar.Rand))
_maxSoFar = new MaxSoFar(value, rnd) {Rand = rnd, Value = value};
}
public void Merge(Random group)
{
if (_maxSoFar.Rand > group._maxSoFar.Rand)
{
_maxSoFar = group._maxSoFar;
}
}
private static int GetRandom()
{
var buffer = new byte[4];
new RNGCryptoServiceProvider().GetBytes(buffer);
return BitConverter.ToInt32(buffer, 0);
}
public SqlString Terminate()
{
return _maxSoFar.Value;
}
#region Nested type: MaxSoFar
private struct MaxSoFar
{
private SqlString _value;
public MaxSoFar(SqlString value, int rand) : this()
{
Value = value;
Rand = rand;
Initialised = true;
}
public SqlString Value
{
get { return _value; }
set
{
_value = value;
IsNull = value.IsNull;
}
}
public int Rand { get; set; }
public bool Initialised { get; set; }
public bool IsNull { get; set; }
}
#endregion
#region IBinarySerialize Members
public void Read(BinaryReader r)
{
_maxSoFar.Rand = r.ReadInt32();
_maxSoFar.Initialised = r.ReadBoolean();
_maxSoFar.IsNull = r.ReadBoolean();
if (_maxSoFar.Initialised && !_maxSoFar.IsNull)
_maxSoFar.Value = r.ReadString();
}
public void Write(BinaryWriter w)
{
w.Write(_maxSoFar.Rand);
w.Write(_maxSoFar.Initialised);
w.Write(_maxSoFar.IsNull);
if (!_maxSoFar.IsNull)
w.Write(_maxSoFar.Value.Value);
}
#endregion
}
答案 1 :(得分:3)
您需要按a.Col1
进行分组才能区分a.Col1
,然后由于b.Col2
未包含在组中,您需要找到合适的聚合函数来减少所有值如果只想要其中一个值,那么该组只有一个,MIN
就足够了。
select a.Col1, MIN(b.Col2) as c2
from a
inner join b on b.Col4=a.Col3
group by a.Col1
答案 2 :(得分:0)
您必须使用group by
子句:
select a.Col1,b.Col2
from a
inner join b on b.Col4=a.Col3
group by a.Col1
答案 3 :(得分:0)
如果我理解正确,您希望第1列和第2列中的每个组合都有一行。可以使用GROUP BY或DISTINCT轻松完成 例如:
SELECT col1,col2
来自你的加入
GROUP BY col1,col2