Reputation: 964
My Table is like
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);
Here i want to extract the field name having values 1 for a given catID. Can any one help me how to write this query in mysql?
I have tried SHOW FIELDS from pricerange but it shows all field names with its details its not dealing with values, SELECT * from pricerange but it needs some php manipulations. But i want to write it in MYSQL only.
Upvotes: 1
Views: 508
Reputation: 44343
The key to solving this problem is to use the information_schema
Here is the query for you:
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';
I loaded your data
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>
Here is the query executed:
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>
It also works in reverse. Here is the same query but hunting down only zeros:
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>
Give it a Try !!!
Upvotes: 1
Reputation: 2947
You could use something like this:
SELECT
GROUP_CONCAT( (IF `Below 500`=1, `Below 500`, ''), (IF `501-1000`=1, `501-1000`, ''),...)
FROM `pricerange`
WHERE `catID`=myCatID
But I would change that DB schema if possible. Have a separate table created and a record for each price interval.
Upvotes: 0
Reputation: 828
Maybe you want to use the case statement... for example
select case "Below 500" when 1 then "Below 500" else "" end,
case "501-1000" when 1 then "501-1000" else "" end, etc...
Upvotes: 0
Reputation: 37354
I don't think SQL is the right tool for that task (given your table structure), it's much easier to read the whole record and get names on client side. But it's possible with sql as well. Idea is to unpivot :
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
etc.
Upvotes: 0