SQL选择是否

时间:2013-12-04 03:32:27

标签: mysql sql

我需要一些帮助..如果DisplayName的值返回null或为fullname,则需要输出FullName的值。

类似

if(u.first_name && u.last_name are not empty)
    output CONCAT(u.first_name,' ',u.last_name) 
else
    output max(case when t.field_id = 1 then t.value else '' end) 
但是怎么样?我的查询花了3.45秒:( ..

SELECT * FROM(  
    SELECT
          t.user_id,
  

##this code
  max(t.field_id = 1然后t.value else''结束时的情况)DisplayName,
  CONCAT(u.first_name,'',u.last_name)FullName,

          max(case when t.field_id = 270 then t.value else '' end) Gender,
          max(case when t.field_id = 274 then t.value else '' end) Birthday,
          max(case when t.field_id = 274 then FLOOR(DATEDIFF(CURRENT_DATE, STR_TO_DATE(t.value,'%m/%d/%Y'))/365)  else '' end) Age,
          max(case when t.field_id = 275 then t.value else '' end) Phone,
          max(case when t.field_id = 286 then t.value else '' end) Email,
          max(case when t.field_id = 71 then t.value else '' end) Occupation,
          max(case when t.field_id = 73 then t.value else '' end) CurrentCountry,   
          max(case when t.field_id = 24 then t.value else '' end) Region,   
          max(case when t.field_id = 355 then t.value else '' end) Province,   
          max(case when t.field_id = 354 then t.value else '' end) City  
    FROM wp_bp_xprofile_data t 
    LEFT JOIN (
        SELECT
        user_id id,
        max(case when meta_key = 'first_name' then meta_value end) first_name,
        max(case when meta_key = 'last_name' then meta_value end) last_name
        from  wp_usermeta  
        GRoup by user_id

    )as u
    ON u.id = t.user_id  
    GROUP BY user_id
)temp 
WHERE 1 = 1  
##Some Condition to be added 
LIMIT 0 , 30

2 个答案:

答案 0 :(得分:1)

我会重复更改为同一个表的多个连接,以使每个字段按照自己的标准 作为表演的可能性。启动配置文件数据一个,以field_id = 1为基础, 然后将所有其余部分加入相同的密钥,然后在每个测试行上没有分组或最大/大小写。 如果某些字段可能不存在,则只需对具有备用别名的重用表进行LEFT-JOIN。 我会确保您的个人资料表上有一个复合/覆盖索引,并带有以下密钥

(user_id,field_id,value)

然后执行以下查询。这里有趣的是,它基本上为每个"组件"打开了相同的表。 user_ID的一部分并将它们排成一行,但仅基于与where子句中的field_id = 1关联的单个记录实例运行查询。所有其他实例都在各自的别名中加入了ON子句。所以现在,我只是遍历field_id = 1的记录,如果在其他表上找到,则抓取值,否则为空(通过合并)。同样加入用户元数据表以获取名字/姓氏。

如果这对您有用,我会有兴趣了解单向性能或其他性能。好处是它不必事先查询每个人(最内层查询)然后运行所有记录的主查询,应用组,然后停在30限制条款。它只是到达前30,其中field_id = 1并完成。现在,如果" field_id = 1"是一个人口稀少的领域,你想与另一个人交换,所以就这样,你比我们更了解你的数据。

SELECT
      DN.User_ID,
      case when fn.user_id is null and ln.user_id is null then DN.value 
           when fn.user_id is null then ln.meta_value
           when ln.user_id is null then fn.meta_value
           else concat( fn.meta_value, ' ', ln.meta_value ) end as FinalName,
      DN.Value DisplayName,
      CONCAT( COALESCE( fn.meta_value, '' ),' ',COALESCE( ln.meta_value, '' )) FullName,
      COALESCE( G.Value, '' ) Gender,
      COALESCE( BD.Value, '' ) Birthday,
      COALESCE( FLOOR( DATEDIFF( CURRENT_DATE, STR_TO_DATE( BD.value,'%m/%d/%Y'))/365), '' ) Age,
      COALESCE( P.Value, '' ) Phone,
      COALESCE( E.Value, '' ) Email,
      COALESCE( O.Value, '' ) Occupation,
      COALESCE( CC.Value, '' ) CurrentCountry,
      COALESCE( R.Value, '' ) Region,
      COALESCE( PR.Value, '' ) Province,
      COALESCE( C.Value, '' ) City
   from
      wp_bp_xprofile_data DN
         LEFT JOIN wp_bp_xprofile_data G
            ON DN.User_ID = G.User_ID AND G.field_id = 270
         LEFT JOIN wp_bp_xprofile_data BD
            ON DN.User_ID = BD.User_ID AND BD.field_id = 274
         LEFT JOIN wp_bp_xprofile_data P
            ON DN.User_ID = P.User_ID AND P.field_id = 275
         LEFT JOIN wp_bp_xprofile_data E
            ON DN.User_ID = E.User_ID AND E.field_id = 286
         LEFT JOIN wp_bp_xprofile_data O
            ON DN.User_ID = O.User_ID AND O.field_id = 71
         LEFT JOIN wp_bp_xprofile_data CC
            ON DN.User_ID = CC.User_ID AND CC.field_id = 73
         LEFT JOIN wp_bp_xprofile_data R
            ON DN.User_ID = R.User_ID AND R.field_id = 24
         LEFT JOIN wp_bp_xprofile_data PR
            ON DN.User_ID = PR.User_ID AND PR.field_id = 355
         LEFT JOIN wp_bp_xprofile_data C
            ON DN.User_ID = C.User_ID AND C.field_id = 354
         LEFT JOIN wp_usermeta FN
            ON DN.User_ID = FN.User_ID AND FN.meta_key = 'first_name'
         LEFT JOIN wp_usermeta LN
            ON DN.User_ID = LN.User_ID AND LN.meta_key = 'last_name'
   where
          DN.field_id = 1
      AND O.Value like '%Programmer%'
   LIMIT 
      0, 30

我修改了使用case / when添加FINAL Name。 如果别名FN / LN(名字/姓氏)都是BOBH null,则获取DN(显示名称)值。否则,我们至少有一个或两个部分的名/姓字段。如果第一个名称为null,则只返回姓氏。如果姓氏为null,则返回第一个名称,否则可以使用名字和姓氏,并返回名称的连续版本。

至于应用额外的WHERE子句。只要添加"必需"针对任何左连接别名的where子句的标准,它将实际上将它们转换为INNER JOIN,并且仅包含那些具有该组件且该组件具有您想要的值的那些......所以,根据您的评论,我会只需添加......

   where
      DN.field_id = 1
      AND BD.User_ID IS NOT NULL
      AND STR_TO_DATE( BD.value,'%m/%d/%Y') BETWEEN '2009-01-01' and '2012-01-01'

您可以使用您的约会年龄并在1到2之间进行,但只是选择感兴趣的日期范围。

关于程序员过滤的其他评论,你的方法是尝试测试所有加入的别名,寻找程序员,但同时,所有这些都是必需的,因为你希望它们都是NOT NULL。如果您需要一个字段,但没有其他特定条件,例如ALWAYS必须有电子邮件地址,那么只需更改

LEFT JOIN wp_bp_xprofile_data E

JOIN wp_bp_xprofile_data E

如果您想确保仅当字段具有空格以外的值(例如您的姓/名)时才会考虑该字段

   LEFT JOIN wp_usermeta FN
      ON DN.User_ID = FN.User_ID 
      AND FN.meta_key = 'first_name' 
      AND LENGTH( TRIM( COALESCE( FN.meta_Value, '' ))) > 0

这将确保仅在实际具有非空字符串值时才考虑记录。

回到你对"%Programmer%' ...的考虑为什么你会期望一个城市,省,地区等拥有程序员的价值。您应该只要求Occupation实例具有该值。此外,因为你有一个OR,它正在做所有的行。你需要包装像

这样的条件
   where
          DN.field_id = 1
      AND (   O.Value like '%Programmer%'
           OR E.Value like '%@gmail.com'
           OR C.Value like 'Some City' )

注意我包装了我的附加标准或组件。这样它仍然只以Field_ID = 1条目开始,但是基于JOIN添加了额外的标准,在这种情况下,DN.field_id = 1总是,但是任何一个(或多个)OR条件也必须为真...职业别名的价值与程序员一样,电子邮件别名的价值为gmail,城市别名如“某些城市”。

希望这澄清了如何实现...另外,请注意,使用任何具有'%'的LIKE限定符引导字符串需要通过整个字符串进行比较,并将查询减慢一些,但由于连接基于用户ID和field_ID值,因此仍应保持快速(相对)。

答案 1 :(得分:0)

试试这个:

SELECT if( trim(CONCAT(first_name,' ', lastName))='', 
           DisplayName, 
           CONCAT(first_name,' ', lastName) ) as Name
     ...rest of the fieds on TA subquery
  FROM (  
    (SELECT
        t.user_id,
        max(case when t.field_id = 1 then t.value else '' end) DisplayName,
        max(case when t.field_id = 270 then t.value else '' end) Gender,
        max(case when t.field_id = 274 then t.value else '' end) Birthday,
        max(case when t.field_id = 274 
           then FLOOR( DATEDIFF( CURRENT_DATE, 
                          STR_TO_DATE( t.value, '%m/%d/%Y')) / 365)  
           else '' end) Age,
        max(case when t.field_id = 275 then t.value else '' end) Phone,
        max(case when t.field_id = 286 then t.value else '' end) Email,
        max(case when t.field_id = 71 then t.value else '' end) Occupation,
        max(case when t.field_id = 73 then t.value else '' end) CurrentCountry,   
        max(case when t.field_id = 24 then t.value else '' end) Region,   
        max(case when t.field_id = 355 then t.value else '' end) Province,   
        max(case when t.field_id = 354 then t.value else '' end) City  
    FROM wp_bp_xprofile_data t 
    GROUP BY user_id
    ) TA 
    LEFT JOIN 
   (   SELECT  user_id id,
                max(case when meta_key = 'first_name' 
                    then meta_value end) first_name,
                max(case when meta_key = 'last_name' 
                    then meta_value end) last_name
          from  wp_usermeta  
         GRoup by user_id ) as U on (ta.user_id = U.id)
)temp 
WHERE 1 = 1  
##Some Condition to be added 
LIMIT 0 , 30