如何动态更改where子句中的列?

时间:2015-09-05 14:02:44

标签: mysql jdbc

我是MySQL新手。我的数据库是客户或webview数据购买的零售产品。例如:

ID  Records
R1  {iphone5s,levis,Dell,Dior,amazon}
R2  {levis,Dell,amazon,Starbucks,google glass}
R3  {iphone5s,Dell,Dior,google glass}
R4  {iphone5s,levis,Starbucks}
R5  {iphone5s,levis,Dell,google glass}

我想将这些数据存储到数据库中。我将此数据存储为:

ID    iphone5s   levis   Dell    Dior   amazon  Starbucks   google glass

R1       1         1      1        1       1         0          0

R2       0         1      1        0       1         1          1

R3       1         0      1        1       0         0          1

R4       1         1      0        0       0         1          0

R5       1         1      1        0       0         0          1


create table retail(ID varchar(50),
                    iphone5s int,
                    levis int,
                    Dell int,
                    Dior int,
                    amazon int,
                    Starbucks int,
                    googleglass int);

insert into retail
values ('r1',1,1,1,1,1,0,0), ('r2',0,1,1,0,1,1,1);

insert into retail
values ('r3',1,0,1,1,0,0,1),('r4',1,1,0,0,0,1,0),('r5',1,1,1,0,0,0,1);

现在我想检索拥有iphone5并存储ID的ID。类似我希望收集ID具有每个列名并存储相应的id。

使用java我通过以下代码收集列名:

ResultSet rs = stmt.executeQuery("SELECT * FROM retail");
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for (int i = 2; i < columnCount + 1; i++ ) {
  String name = rsmd.getColumnName(i);
}

现在我想从零售where columnname=1中选择ID。

每次都应更改列名。

2 个答案:

答案 0 :(得分:1)

从评论到问题:

  

还有其他更好的方法可以将上述原始数据存储在数据库系统中吗?

绝对。您应该将购买的每件商品存储在一个单独的行中,如下所示:

ID  item
--  ------------
R1  iphone5s
R1  levis
R1  Dell
R1  Dior
R1  amazon
R2  levis
R2  Dell
R2  amazon
R2  Starbucks
R2  google glass
...

这样可以更容易查询(因为列名称是常量),如果您需要添加新产品,则无需更改数据库结构。您可以随时将数据“旋转”为现在的格式,但不应该以这种方式存储。

答案 1 :(得分:0)

您可以在MySQL中使用UNPIVOT等效项。现在,您只需使用WHERE brand = 'name' AND is_available = 1

进行查询即可

<强> SqlFiddleDemo

create table retail(ID varchar(50),
                    iphone5s int,
                    levis int,
                    Dell int,
                    Dior int,
                    amazon int,
                    Starbucks int,
                    googleglass int);

insert into retail
values ('r1',1,1,1,1,1,0,0), ('r2',0,1,1,0,1,1,1),
       ('r3',1,0,1,1,0,0,1),('r4',1,1,0,0,0,1,0),('r5',1,1,1,0,0,0,1);

select id
from
(
  select
    t.id,
    c.brand,
    case c.brand
      when 'iphone5s'    then iphone5s
      when 'levis'       then levis
      when 'Dell'        then Dell
      when 'Dior'        then Dior
      when 'amazon'      then amazon
      when 'Starbucks'   then Starbucks
      when 'googleglass' then googleglass 
    end as is_available
  from retail t
  cross join
  (
    select 'iphone5s' as brand
    union all
    select 'levis'
    union all
    select 'Dell'
    union all
    select 'Dior'
    union all 
    select 'amazon'
    union all
    select 'Starbucks'
    union all
    select 'googleglass'
  ) c
) temp
where brand = 'iphone5s'   /* Here your brand/product_name */
  and is_available = 1
order by id;              /* If needed */

<强> SqlFiddleDemo_UNPIVOT_TSQL

WITH cte AS
(
  SELECT ID, Brand, Val
  FROM
  (
     SELECT Id, iphone5s, levis, Dell, Dior, amazon, Starbucks, googleglass
     FROM retail
   ) t
   UNPIVOT
   (
     Val FOR Brand IN (iphone5s, levis, Dell,
                    Dior, amazon, Starbucks, googleglass)
    ) AS mrks
)
SELECT ID
FROM cte
WHERE Brand = 'Dior' 
AND [val] = 1;