从Sql Server中的逗号分隔值比较Id

时间:2016-10-01 11:21:49

标签: sql-server azure-sql-database

我有一个列,其中UserIds以逗号分隔的形式存储(如下所示)。现在我遇到一个问题,我需要检查当前用户是否在该列表中可用。

Id     UserId 
--  ---------------
1    10,11,12,13    
2    10,13,15,4     

我已经使用了分割功能,但这花费了太多时间,因为我有数百万条记录,还有20个其他列。

6 个答案:

答案 0 :(得分:1)

检查这些逗号分隔列表的另一个时髦解决方案是:

示例数据

Declare @Table TABLE(Id INT,UserId VARCHAR(50))
INSERT INTO @Table VALUES
( 1  ,  '10,11,12,13'),    
( 2  ,  '10,13,15,4'); 

查询

Declare @UserIDToCheck INT = 10;   --<-- Id to check 

SELECT * 
FROM (
    SELECT    Id
            , RTRIM(LTRIM(Split.a.value('.', 'VARCHAR(100)'))) UserID
    FROM   
        (
        SELECT   Id
                , Cast ('<X>' + Replace(UserId, ',', '</X><X>') + '</X>' AS XML) AS Data
        FROM    @Table
        ) AS t 
        CROSS APPLY Data.nodes ('/X') AS Split(a) 
)A
WHERE UserID = @UserIDToCheck 

注意

但最重要的是,您需要修复架构,如果您使用任何关系数据库来存储数据,请以正确的方式执行,遵循规范化的简单和非常基本的规则。

您的架构目前违反了规范化的第一条规则。至少让你的数据库符合前3个规范化规则,它将使管理你的应用程序和你的生活变得更加容易和简单:)。

答案 1 :(得分:1)

试一试:

class Time_model extends CI_model
{
    public $time_zone;
    public $tz;
    public $dt;

    public function __construct()
    {
        date_default_timezone_set('UTC');
        $this->time_zone = 'Pacific/Auckland';

        $this->tz = new DateTimeZone($this->time_zone);
        $this->dt = new DateTime('now', $this->tz);
    }

    /**
     * dates
     */

    public function getDate()
    {
        $this->dt->getTimezone(); // <--- shows that the timezone is auckland where it is the 02/10/2016 
        return $this->dt->format('Y-m-d'); // <--- yet returns the 01/10/2016! 
    }
}

答案 2 :(得分:0)

我找到了以下解决上述问题的方法。

SELECT * 
FROM dbo.History 
WHERE (','+ RTRIM(ShareWith)+',') LIKE '%,'+CAST(@UserId AS VARCHAR)+',%') 

答案 3 :(得分:0)

您可以使用XML从逗号分隔值中获取表格:

DECLARE @x xml,
        @UserId int = 10

SELECT @x = (
    SELECT  id as '@id',
            CAST('<u>'+REPLACE(UserId,',','</u><u>') +'</u>' as xml)
    FROM YourTable
    FOR XML PATH('row')
)

SELECT  t.v.value('../@id','int') as id
FROM @x.nodes('/row/u') as t(v)
WHERE t.v.value('.','int') = @UserId

输出:

id
1
2

答案 4 :(得分:0)

您使用过自定义分割功能还是标准STRING_SPLIT?在Azure Sql Database中,您可以使用STRING_SPLIT函数来拆分字符串:

SELECT mytable.*
FROM mytable
     CROSS APPLY STRING_SPLIT(UserId , ',') ids
WHERE ids.value = 3

答案 5 :(得分:0)

尝试(如果您使用的是 php)

$id = $checkId;
$sql= "SELECT * FROM TableName WHERE ColumnName like '%,". $id .",%' or ColumnName like 
      '". $id .",%' or ColumnName like '%,". $id ."' or ColumnName = ". $id;