SQL Select语句中的动态列 [英] Dynamic Columns in SQL Select statement

查看:104
本文介绍了SQL Select语句中的动态列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题被标记为与该问题重复" mySQL-使用数据创建新表和三个表中的列

This Question was marked as beeing a "duplicate" of the question mySQL - Create a New Table Using Data and Columns from Three Tables

我认为问题是不同的,因为实际上有三个表,而我的问题是两个.那里的问题是如何创建一个新表,这里的问题是要创建一个输出. 但是感谢您的指点,也许它比我的预期更接近我的问题.

I think the question is different, because there are three tables in action, in my question are two. There the question is how to create a new table, here the question is to create an output. But thanks for pointing, maybe it's closer to my problem than I expecting.

我尝试使用重复"问题中的解决方案,但是答案和问题并不十分相似.

I tried to use the solutions from the "Duplicate"-Question, but the Ansers and the problems are not very simmilar.

我也尝试过重复"问题

SELECT i.ID as ItemID, i.Name as ItemName, 
       p1.Value AS Color, p2.Value AS Speed, p3.Value AS Price
FROM items as i
JOIN itemproperties AS p1 ON (i.ID=p1.ItemID)
JOIN itemproperties AS p2 ON (i.ID=p2.ItemID)
JOIN itemproperties AS p3 ON (i.ID=p3.ItemID)
WHERE (p1.Name = 'Color') and (p2.Name = 'Speed') and (p3.Name = 'Price')

但是结果只有一行

ItemID, ItemName, Color, Speed, Price
1,      Car,      blue,    200, 50000

没有预期的四行,在没有属性名称的地方包含值(NULL)".

Instead of the expected four lines, containing the value "(NULL)" at the places where no property name is found.

所以恕我直言,重复"问题与众不同,没有回答我的问题!

So IMHO the "Duplicate"-Question is different and did not answer my question!

原始问题:

我的个人SQL技能是有限的.环顾了几天后,我在下面的数据库查询问题中找不到任何有效的解决方案.我在此问题的末尾附加了完整的示例数据库SQL文本. 我的示例数据库(由MariaDB创建)包含两个表:

My personal SQL skills are limited. After looking around for several days, I did not find any working solution for my database query problem below. I attached the full example Database SQL-text at the end of this question. My example database (made with MariaDB) contains two tables:

  • 项目和
  • itemproperties.

对于每个项目,仅定义一个 item.ID 和一个 item.Name . (在现实生活中,该名称将定义为唯一.)

For each item only an item.ID and an item.Name is defined. (In a real life example, the name would be defined to be unique.)

对于每个项目,动态的用户定义属性集都是可能的.这些属性被定义为名称-值对. 例如,对于名为"香蕉"的项目,可能存在值为"黄色"的属性"颜色".

For each item an dynamic user defined set of properties is possible. These properties are defined as a name-value-pair. For example, for an item named "Banana" a property "Color" with the value "yellow" may exists.

只有一项具有颜色"属性是有效的,因此不能将两种不同的颜色分配给一项.

It is only valid to have one "Color" property for one item, so that not two different colors could be assigned to one item.

(在我的现实世界中,属性名称仅包含两个字符,因此不需要附加的属性名称表,随后为了易于显示示例中未使用的问题).

(In my real world problem the property names contains only two characters, so an additional property name table is not necessary, and subsequently for the ease of showing the problem not used in the example).

items表的示例数据:

The example data for the items table:

ID, Name
1,  Car
2,  House
3,  Homer
4,  Earth

以上项共定义了9个属性.条目(NULL)"表示未为给定项目定义此属性

And a total of nine properties for the items above are defined. The entry "(NULL)" are indicating that this property is not defined for a given item

ItemID, ItemName, Color,    Speed,  Price
1,      Car,      blue,       200,  50000
2,      House,    red,     (NULL), 250000
3,      Homer,    yellow,       5, (NULL)
4,      Earth,    blue,    108000, (NULL)

不幸的是我的选择语句

SELECT items.ID as ItemID, items.Name as ItemName,
CASE WHEN (itemproperties.Name = 'Color')
       THEN itemproperties.Value
       #ELSE NULL
END as Color,
CASE WHEN (itemproperties.Name = 'Speed')
       THEN itemproperties.Value
       #ELSE NULL
END as Speed,
CASE WHEN (itemproperties.Name = 'Price')
       THEN itemproperties.Value
       #ELSE NULL
END as Price
FROM items left join itemproperties 
ON  (items.ID=itemproperties.ItemID)

返回这样的数据

ItemID, ItemName, Color,   Speed, Price
1,      Car,      blue,   (NULL), (NULL)
1,      Car,      (NULL),  200,   (NULL)
1,      Car,      (NULL), (NULL), 50000
2,      House,    red,    (NULL), (NULL)
2,      House,    (NULL), (NULL), 250000
3,      Homer,    yellow, (NULL), (NULL)
3,      Homer,    (NULL),      5, (NULL)
4,      Earth,    blue,   (NULL), (NULL)
4,      Earth,    (NULL), 108000, (NULL)

问题:如何编写select语句以整理形式获取数据,每一项对应一行? 非常感谢你!

Question: How to write the select statement to get tha data in a collated form, one row for each item? Thank you very much!

Ekkehard的问候

Greetings Ekkehard

数据库定义:

-- --------------------------------------------------------
-- Host:                         127.0.0.1
-- Server Version:               10.1.13-MariaDB - mariadb.org binary distribution
-- Server Betriebssystem:        Win32
-- HeidiSQL Version:             9.4.0.5125
-- --------------------------------------------------------

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;


-- Exportiere Datenbank Struktur für DynamicColTest
CREATE DATABASE IF NOT EXISTS `dynamiccoltest` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `DynamicColTest`;

-- Exportiere Struktur von Tabelle DynamicColTest.itemproperties
CREATE TABLE IF NOT EXISTS `itemproperties` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique ID of the property',
  `ItemID` int(10) unsigned DEFAULT '0' COMMENT 'ID of the Item this property belongs to',
  `Name` varchar(20) DEFAULT '0' COMMENT 'Name of the property',
  `Value` varchar(20) DEFAULT '0' COMMENT 'Value of the property',
  UNIQUE KEY `Schlüssel 3` (`Name`,`ItemID`),
  KEY `Schlüssel 1` (`ID`),
  KEY `FK_itemproperties_items` (`ItemID`),
  CONSTRAINT `FK_itemproperties_items` FOREIGN KEY (`ItemID`) REFERENCES `items` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 COMMENT='The properties of the items';

-- Exportiere Daten aus Tabelle DynamicColTest.itemproperties: ~9 rows (ungefähr)
DELETE FROM `itemproperties`;
/*!40000 ALTER TABLE `itemproperties` DISABLE KEYS */;
INSERT INTO `itemproperties` (`ID`, `ItemID`, `Name`, `Value`) VALUES
    (1, 1, 'Color', 'blue'),
    (1, 4, 'Color', 'blue'),
    (1, 2, 'Color', 'red'),
    (2, 3, 'Color', 'yellow'),
    (3, 1, 'Speed', '200'),
    (3, 4, 'Speed', '108000'),
    (4, 3, 'Speed', '5'),
    (5, 1, 'Price', '50000'),
    (5, 2, 'Price', '250000');
/*!40000 ALTER TABLE `itemproperties` ENABLE KEYS */;

-- Exportiere Struktur von Tabelle DynamicColTest.items
CREATE TABLE IF NOT EXISTS `items` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique Item ID',
  `Name` varchar(25) DEFAULT '0' COMMENT 'Name of the Item',
  KEY `Schlüssel 1` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 COMMENT='Contains all Items, with a minimum of definitions';

-- Exportiere Daten aus Tabelle DynamicColTest.items: ~4 rows (ungefähr)
DELETE FROM `items`;
/*!40000 ALTER TABLE `items` DISABLE KEYS */;
INSERT INTO `items` (`ID`, `Name`) VALUES
    (1, 'Car'),
    (2, 'House'),
    (3, 'Homer'),
    (4, 'Earth');
/*!40000 ALTER TABLE `items` ENABLE KEYS */;

/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

推荐答案

您可以通过以下方式在没有每个属性联接的情况下执行此操作:

You can do this without a join per attribute this way:

SELECT i.ID, i.Name,
  MAX(IF(p.Name='Color', p.value, NULL)) AS Color,
  MAX(IF(p.Name='Speed', p.value, NULL)) AS Speed,
  MAX(IF(p.Name='Price', p.value, NULL)) AS Price
FROM items i
LEFT JOIN itemproperties p 
ON  (i.ID=p.ItemID)
GROUP BY i.ID

输出:

+----+-------+--------+--------+--------+
| ID | Name  | Color  | Speed  | Price  |
+----+-------+--------+--------+--------+
|  1 | Car   | blue   | 200    | 50000  |
|  2 | House | red    | NULL   | 250000 |
|  3 | Homer | yellow | 5      | NULL   |
|  4 | Earth | blue   | 108000 | NULL   |
+----+-------+--------+--------+--------+

但是使用EAV数据总是很尴尬和冒险.如果可以,请避免使用它.

But working with EAV data is always awkward and risky. Avoid it if you can.

PS:另外,您还应该为自己的项目表声明一个主键约束.

PS: Also you should declare a primary key constraint for your items table.

alter table items add primary key (ID);

这篇关于SQL Select语句中的动态列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆