【问题标题】:How to extract field name from table having values as 1?如何从值为 1 的表中提取字段名称?
【发布时间】:2012-07-23 04:31:27
【问题描述】:

我的桌子是这样的

CREATE TABLE IF NOT EXISTS `pricerange` (
  `priceRangeID` int(11) NOT NULL AUTO_INCREMENT,
  `catID` int(11) NOT NULL,
  `Below 500` tinyint(1) NOT NULL DEFAULT '0',
  `501-1000` tinyint(1) NOT NULL DEFAULT '0',
  `1001-2000` tinyint(1) NOT NULL DEFAULT '0',
  `2001-3000` tinyint(1) NOT NULL DEFAULT '0',
  `3001-4000` tinyint(1) NOT NULL DEFAULT '0',
  `4001-5000` tinyint(1) NOT NULL DEFAULT '0',
  `5001-6000` tinyint(1) NOT NULL DEFAULT '0',
  `6001-7000` tinyint(1) NOT NULL DEFAULT '0',
  `7001-8000` tinyint(1) NOT NULL DEFAULT '0',
  `8001-9000` tinyint(1) NOT NULL DEFAULT '0',
  `9001-10000` tinyint(1) NOT NULL DEFAULT '0',
  `10001-100000` tinyint(1) NOT NULL DEFAULT '0',
  `above 100000` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`priceRangeID`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

INSERT INTO `pricerange` (`priceRangeID`, `catID`, `Below 500`, `501-1000`, `1001-2000`, `2001-3000`, `3001-4000`, `4001-5000`, `5001-6000`, `6001-7000`, `7001-8000`, `8001-9000`, `9001-10000`, `10001-100000`, `above 100000`) VALUES
(1, 3, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1);

在这里,我想为给定的 catID 提取值为 1 的字段名称。谁能帮我在mysql中写这个查询?

我尝试过 SHOW FIELDS from pricerange,但它显示了所有字段名称及其详细信息,它不处理值,SELECT * from pricerange 但它需要一些 php 操作。但我只想用 MYSQL 编写它。

【问题讨论】:

  • 为什么价值可以在多个价格区间共存?
  • 我的客户想从这个表中选择一个类别的范围。
  • 存储过程有什么办法吗?

标签: mysql


【解决方案1】:

解决这个问题的关键是使用information_schema

这是给你的查询:

SELECT A.column_name FROM
(select ordinal_position-3 pos,column_name from information_schema.columns
where table_name='pricerange' and LOCATE('-',column_name)) A
INNER JOIN
(SELECT CONCAT(`501-1000`,`1001-2000`,`2001-3000`,
`3001-4000`,`4001-5000`,`5001-6000`,`6001-7000`,
`7001-8000`,`8001-9000`,`9001-10000`,
`10001-100000`) bitmap FROM pricerange) B
ON SUBSTR(bitmap,pos,1) = '1';

我加载了你的数据

mysql> DROP DATABASE IF EXISTS sumant;
Query OK, 1 row affected (0.06 sec)
mysql> CREATE DATABASE sumant;
Query OK, 1 row affected (0.00 sec)
mysql> USE sumant
Database changed
mysql> CREATE TABLE IF NOT EXISTS `pricerange` (
    ->   `priceRangeID` int(11) NOT NULL AUTO_INCREMENT,
    ->   `catID` int(11) NOT NULL,
    ->   `Below 500` tinyint(1) NOT NULL DEFAULT '0',
    ->   `501-1000` tinyint(1) NOT NULL DEFAULT '0',
    ->   `1001-2000` tinyint(1) NOT NULL DEFAULT '0',
    ->   `2001-3000` tinyint(1) NOT NULL DEFAULT '0',
    ->   `3001-4000` tinyint(1) NOT NULL DEFAULT '0',
    ->   `4001-5000` tinyint(1) NOT NULL DEFAULT '0',
    ->   `5001-6000` tinyint(1) NOT NULL DEFAULT '0',
    ->   `6001-7000` tinyint(1) NOT NULL DEFAULT '0',
    ->   `7001-8000` tinyint(1) NOT NULL DEFAULT '0',
    ->   `8001-9000` tinyint(1) NOT NULL DEFAULT '0',
    ->   `9001-10000` tinyint(1) NOT NULL DEFAULT '0',
    ->   `10001-100000` tinyint(1) NOT NULL DEFAULT '0',
    ->   `above 100000` tinyint(1) NOT NULL DEFAULT '0',
    ->   PRIMARY KEY (`priceRangeID`)
    -> ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
Query OK, 0 rows affected (0.17 sec)

mysql> INSERT INTO `pricerange` (`priceRangeID`, `catID`, `Below 500`, `501-1000`, `1001-2000`, `2001-3000`, `3001-4000`, `4001-5000`, `5001-6000`, `6001-7000`, `7001-8000`, `8001-9000`, `9001-10000`, `10001-100000`, `above 100000`) VALUES
    -> (1, 3, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1);
Query OK, 1 row affected (0.07 sec)

mysql>

这是执行的查询:

mysql> SELECT A.column_name FROM
    -> (select ordinal_position-3 pos,column_name from information_schema.columns
    -> where table_name='pricerange' and LOCATE('-',column_name)) A
    -> INNER JOIN
    -> (SELECT CONCAT(`501-1000`,`1001-2000`,`2001-3000`,
    -> `3001-4000`,`4001-5000`,`5001-6000`,`6001-7000`,
    -> `7001-8000`,`8001-9000`,`9001-10000`,
    -> `10001-100000`) bitmap FROM pricerange) B
    -> ON SUBSTR(bitmap,pos,1) = '1';
+--------------+
| column_name  |
+--------------+
| 5001-6000    |
| 6001-7000    |
| 9001-10000   |
| 10001-100000 |
+--------------+
4 rows in set (0.02 sec)

mysql>

它也可以反向工作。这是相同的查询,但只查找零:

mysql> SELECT A.column_name FROM
    -> (select ordinal_position-3 pos,column_name from information_schema.columns
    -> where table_name='pricerange' and LOCATE('-',column_name)) A
    -> INNER JOIN
    -> (SELECT CONCAT(`501-1000`,`1001-2000`,`2001-3000`,
    -> `3001-4000`,`4001-5000`,`5001-6000`,`6001-7000`,
    -> `7001-8000`,`8001-9000`,`9001-10000`,
    -> `10001-100000`) bitmap FROM pricerange) B
    -> ON SUBSTR(bitmap,pos,1) = '0';
+-------------+
| column_name |
+-------------+
| 501-1000    |
| 1001-2000   |
| 2001-3000   |
| 3001-4000   |
| 4001-5000   |
| 7001-8000   |
| 8001-9000   |
+-------------+
7 rows in set (0.01 sec)

mysql>

试试看!!!

【讨论】:

    【解决方案2】:

    你可以这样使用:

    SELECT
    GROUP_CONCAT( (IF `Below 500`=1, `Below 500`, ''), (IF `501-1000`=1, `501-1000`, ''),...)
    FROM `pricerange`
    WHERE `catID`=myCatID
    

    但如果可能,我会更改该数据库架构。为每个价格区间创建一个单独的表并记录。

    【讨论】:

      【解决方案3】:

      也许您想使用 case 语句...例如

      select case "Below 500" when 1 then "Below 500" else "" end, 
             case "501-1000" when 1 then "501-1000" else "" end, etc...
      

      【讨论】:

        【解决方案4】:

        我认为 SQL 不是该任务的正确工具(鉴于您的表结构),读取整个记录并在客户端获取名称要容易得多。但也可以使用 sql。想法是反透视:

        SELECT 'Below 500' as field1
        FROM  pricerange where catID = 1 AND `Below 500` is not null
        UNION ALL
        SELECT '501-1000' as field1
        FROM  pricerange where catID = 1 AND `501-1000` is not null
        

        等等。

        【讨论】:

          猜你喜欢
          • 2021-11-19
          • 2013-03-04
          • 1970-01-01
          • 2011-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多