我正在使用MySQL中的一个表,其中包含以下列:
id, january, february, march, april, etc
表中的数据如下所示:
aa, 0, 0, 1, 0
ab, 1, 0, 1, 0
ac, 1, 1, 0, 0
ad, 1, 1, 1, 0
要查询它,我可以轻松地执行此操作:
select * from table where january = 1 and february = 1
结果将是:
ac, 1, 1, 0, 0
ad, 1, 1, 1, 0
我想知道是否有办法这样做:
select * from table where table.columns = 1
我想在表达式中使用表列而不实际手动指定名称(键入它们)。
加分(+1)问题:
可以像这样使用Match / Against来完成:
select * from table
where
(
match (somehow,get,the,table,columns,I,need,here)
against (1 in boolean mode)
)
感谢您的时间! :)
答案 0 :(得分:4)
您必须使用Prepared Statement,因为您只想使用动态SQL来完成:
SET @stmt = 'SELECT * FROM YOUR_TABLE WHERE 1 = 1 '
SET @stmt = CONCAT(@stmt, (SELECT CONCAT_WS(' AND ', CONCAT(column_name, ' = 1 '))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'YOUR_TABLE'
AND table_schema = 'db_name'
AND column_name NOT IN ('id')));
PREPARE stmt FROM @stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
第一个SET语句构造一个基本的SELECT语句; “1 = 1”部分就是为了更容易连接“AND column = 1
”
第二个SET语句将查询的内容连接起来,以便根据表名在第一个SET语句的字符串末尾获取列的列表。这个想法是这样的:
SELECT CONCAT_WS(' AND ', CONCAT(column_name, ' = 1 '))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'YOUR_TABLE'
AND table_schema = 'db_name'
AND column_name NOT IN ('id')
...将返回类似“AND january = 1 AND february = 1 ...
”的行。如果在WHERE子句中还有其他不需要的列,则必须更新NOT IN子句。
其余的只是标准的预备语句,这一切都必须在存储过程中进行。
答案 1 :(得分:1)
我明白史密斯先生正在努力做什么。
这是一个12行x 4列与1行x 12列的问题。
以前的表格设计类似于:
id,某人的身份,月份,每月x 12
1, 101, january, 1
2, 101, february, 1
3, 101, march, 0
etc..
对应的sql语句是:
$sqlQuery = "SELECT month FROM my_month_table WHERE value = 1";
我猜猜史密斯先生正在尝试:
id,某人的身份,1月,2月,3月......
$sqlQuery = "SELECT corrensponding_column_names_to_where_clause FROM my_month_table WHERE column_value = 1";
答案 2 :(得分:1)
你可以使用match ...对抗它。
在这种情况下,您的表必须是MyISAM表,您必须创建包含必需列的FULLTEXT索引。
答案 3 :(得分:1)
尝试创建视图
CREATE VIEW v_months
AS
SELECT *, CONCAT( CAST(jan AS CHAR(1)),
CAST(feb AS CHAR(1)),
CAST(mar AS CHAR(1)),
...) AS all
FROM months
你会得到这样的东西:
aa, 0, 0, 1, 0, 0010
ab, 1, 0, 1, 0, 1010
ac, 1, 1, 0, 0, 1100
ad, 1, 1, 1, 0, 1110
然后你可以查询
SELECT * FROM v_months WHERE all = '100110010101'
或者,如果您想要查询“获取所有行,其中feb = 1”,您可以这样写:
SELECT * FROM v_months WHERE all LIKE '_1____________'
其中'_'恰好匹配一个字符。
答案 4 :(得分:0)
您可以在MySQL中使用向量:
select * from table where (january, february) = (1, 1)
请注意文本列的不同服务器和客户端排序规则,然后您可能需要明确指定排序规则。
答案 5 :(得分:0)
在我看来,这是由于桌面设计看起来很糟糕(我猜这只是一个简单问题的例子,但请耐心等待,我认为这个概念可以更好地建模。
以下是表格:
Things Things_Months Months
thing_id thing_id Month_id
thing_info month_id Month_Name
thing_month_id order_field
这里是sql:
select thing_info, month_name
from things, things_months, months
where things.thing_id = things_months.thing_id
and things_months.month_id = months.month_id
order by things.things_info, months.order_field
结果将是
thingy 1, January
thingy 1, February
thingy 2, April
thingy 3, November
thingy 3, December
答案 6 :(得分:0)
select * from table where 1 in (january, february)
答案 7 :(得分:0)
如何使用VIEW解决问题?
CREATE TABLE `d001ab05`.`months` (
`id` INT NOT NULL ,
`jan` BOOL NOT NULL ,
`feb` BOOL NOT NULL ,
`mar` BOOL NOT NULL ,
`apr` BOOL NOT NULL ,
`may` BOOL NOT NULL ,
`jun` BOOL NOT NULL ,
`jul` BOOL NOT NULL ,
`aug` BOOL NOT NULL ,
`sep` BOOL NOT NULL ,
`oct` BOOL NOT NULL ,
`nov` BOOL NOT NULL ,
`dec` BOOL NOT NULL ,
PRIMARY KEY ( `id` )
) ENGINE = InnoDB;
插入数据:
INSERT INTO `d001ab05`.`months` (
`id`, `jan`, `feb`, `mar`, `apr`, `may`, `jun`,
`jul`, `aug`, `sep`, `oct`, `nov`, `dec`
) VALUES (
'1', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'
), (
'2', '1', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'
), (
'3', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'
), (
'4', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'
);
使用选择查看:
CREATE OR REPLACE VIEW `moncase` AS
SELECT id,
CASE WHEN `jan` =1 OR `feb` =1 OR `mar` =1 OR `apr` =1 OR `may` =1 OR
`jun` =1 OR `jul` =1 OR `aug` =1 OR `sep` =1 OR `oct` =1 OR `nov` =1 OR `dec` =1
THEN 1 ELSE 0 END AS or_over_months
FROM months;
选择
SELECT * FROM `moncase` WHERE `or_over_months` = 1;
结果:
id | or_over_months
1 | 1
2 | 1
4 | 1
答案 8 :(得分:0)
您需要的是非转轴操作。 Microsoft SQL Server支持PIVOT
和UNPIVOT
作为标准SQL的扩展。我不知道任何其他品牌的RDBMS支持内置的pivot / unpivot功能。当然MySQL不支持这个。
在这种情况下,您无法使用FULLTEXT
搜索,因为作为文档say:
全文索引只能与MyISAM表一起使用,并且只能为CHAR,VARCHAR或TEXT列创建。
并且无论如何都不会让您无需指定列,因为MATCH()
谓词需要您在全文索引中列出所有列。
如果您无法重新构建表以存储每月行或单个列来编码所有12个月,那么您需要生成动态SQL。