如何从具有不同行值的列中从现有表中创建新表?

发布于 2025-02-10 18:26:36 字数 869 浏览 1 评论 0原文

我的表 tansactions 看起来像这样 -

我想制作一个单独的客户表,在上升顺序和相关的'Market_code','Market_name'和'Zone'列中具有独特的'Customer_Code'。 结果表看起来像这样 - ”描述在这里“

我尝试过 -

create table customers as (
select customer_code, market_code, market_name, zone 
from transactions group by customer_code);

这在MySQL Workbench上正常工作,但对PGADMIN不起作用。

I have table tansactions that looks like this -
enter image description here

I want to make a separate customers table that has distinct 'customer_code' in ascending order and related 'market_code','market_name', and 'zone' columns.
the resultant table would look like this -
enter image description here

I have tried -

create table customers as (
select customer_code, market_code, market_name, zone 
from transactions group by customer_code);

This works fine on MySQL workbench but doesn't work on PGadmin.

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

春风十里 2025-02-17 18:26:36

您问两个问题:

  1. 为什么我的创建表语句在MySQL中运行而不是在PostgreSQL中运行?
  2. 如何编写正确的创建表语句?

MySQL与PostgreSQL

关于第一个问题, :您的查询无效。您通过customer_code进行分组,然后选择market_code。但是一个customer_code有很多行,那么它的哪个corket_codes可以选择?您忘了告诉DBMS。因此,两个DBM都应该丢失错误。如果MySQL没有,这可能意味着您正在使用一个旧的MySQL版本,该版本设置为MySQL在 by group by 子句中发明的作弊模式,从开始。确保设置sql_mode ='halle_full_group_by';在mySQL中以在触发此类无效查询时获取正确的语法错误消息 - 或使用当前的mySQL版本,其中此模式为默认模式。

至于第二个问题,这并不容易回答...

数据库归一化

您正在处理一个非正态表的表。它一次又一次地在同一区域中显示同一客户。这很容易出错。您期望同一客户始终处于同一市场,但是如果某些交易并非如此,该怎么办?您期望属于一个市场名称的代码,但是如果表格中并非总是如此,该怎么办?您期望一个市场进入一个区域,如果所有交易并非如此,又要呢?

假设您的所有期望都是有效的,并且违反这些期望的数据是错误的。

纠正矛盾之

处,因此首先找到数据不一致。我在这里使用PostgreSQL,因为尽管有MySQL标签,这似乎是您要使用的。

select customer_code, string_agg(distinct market_code, ',' order by market_code)
from transactions
group by customer_code
having count(distinct market_code) > 1;

如果此查询用多个Markt重新调整客户,请修复您的数据。例如:

update transactions
set market_code = 'Mark001'
where customer_code = 'Cus001';

市场代码相同。查询:

select market_code, string_agg(distinct market_name, ',' order by market_name)
from transactions
group by market_code
having count(distinct market_name) > 1;

不一致的数据更新:

update transactions
set market_name = 'Darbhanga'
where market_code = 'Mark001';

市场区域相同。查询:

select market_code, string_agg(distinct zone, ',' order by zone)
from transactions
group by market_code
having count(distinct zone) > 1;

不一致的数据更新:

update transactions
set zone = 'Bihar'
where market_code = 'Mark001';

数据库后,将表格归一化

完成 ,构建表。是的,没有一个客户表,因为这仍然是不归一化的,并且承担同样的风险。相反,我们有区域,市场,客户和交易。

您可以单独使用技术ID或坚持使用代码。我在这里根据您的代码来构建桌子,但选择是您的。

区域

create table zone
(
  zone_code varchar(100) not null,
  zone      varchar(100) not null,
  primary key (zone_code),
  unique (zone)
);

insert into zone (zone_code, zone)
  select distinct upper(zone), zone
  from transactions;

市场

create table market
(
  market_code varchar(100) not null,
  name        varchar(100) not null,
  zone_code   varchar(100) not null,
  primary key (market_code),
  unique (name),
  constraint fk_market_zone foreign key(zone_code) references zone(zone_code)
);

insert into market (market_code, name, zone_code)
  select distinct market_code, market_name, upper(zone)
  from transactions;

客户

create table customer
(
  customer_code varchar(100) not null,
  market_code varchar(100) not null,
  primary key (customer_code),
  constraint fk_customer_market foreign key(market_code) references market(market_code)
);

insert into customer (customer_code, market_code)
  select distinct customer_code, market_code
  from transactions;

交易

从表中删除了现在的冗余列。他们现在与客户隐含。

alter table transactions
  drop column market_code,
  drop column market_name,
  drop column zone;

You are asking two questions:

  1. Why does my create table statement run in MySQL and not in postgreSQL?
  2. How to write the proper create table statement?

MySQL vs. PostgreSQL

As to the first question: Your query is invalid. You group by customer_code and select the market_code. But there are many rows for one customer_code, so which of its market_codes to pick? You forgot to tell the DBMS. Hence both DBMS should throw an error. If MySQL doesn't, this probably means that you are working with an old MySQL version that is set to a cheat mode that MySQL invented when they had problems with GROUP BY clauses and functional dependencies ín the beginning. Make sure to SET sql_mode = 'ONLY_FULL_GROUP_BY'; in MySQL to get a proper syntax error message when wrting such invalid queries - or use a current MySQL version where this mode is the default.

As to the second question, this is not so easy to answer...

Database normalization

You are dealing with a non-normalized table. It shows the same customer in the same market in the same zone again and again. And this is prone to errors. You expect the same customer to always be in the same market, but what if this isn't the case with some transactions? You expect a code belonging to exactly one market name, but what if this is not always the case in the table? You expect one market to be in one zone, and again, what if this is not the case with all transactions?

Let's say that all your expectations are valid, and data violating these expectations is erroneous.

Correcting inconsistencies

So, find data inconsistencies first. I am using PostgreSQL here as this seems to be what you want to use in spite of the MySQL tag.

select customer_code, string_agg(distinct market_code, ',' order by market_code)
from transactions
group by customer_code
having count(distinct market_code) > 1;

If this query retuns customers with more than one markt, fix your data. E.g.:

update transactions
set market_code = 'Mark001'
where customer_code = 'Cus001';

Same for market codes. The query:

select market_code, string_agg(distinct market_name, ',' order by market_name)
from transactions
group by market_code
having count(distinct market_name) > 1;

Update of inconsistent data:

update transactions
set market_name = 'Darbhanga'
where market_code = 'Mark001';

Same for market zones. The query:

select market_code, string_agg(distinct zone, ',' order by zone)
from transactions
group by market_code
having count(distinct zone) > 1;

Update of inconsistent data:

update transactions
set zone = 'Bihar'
where market_code = 'Mark001';

Normalizing the database

Once this is done, build your tables. Yes, not one customer table alone, because this would still be non-normalized and bear the same risk. Instead, we have zones, markets, customers, and transactions.

You can use technical IDs or stick to your codes alone. I am building the tables based on your codes here, but the choice is yours.

Zones

create table zone
(
  zone_code varchar(100) not null,
  zone      varchar(100) not null,
  primary key (zone_code),
  unique (zone)
);

insert into zone (zone_code, zone)
  select distinct upper(zone), zone
  from transactions;

Markets

create table market
(
  market_code varchar(100) not null,
  name        varchar(100) not null,
  zone_code   varchar(100) not null,
  primary key (market_code),
  unique (name),
  constraint fk_market_zone foreign key(zone_code) references zone(zone_code)
);

insert into market (market_code, name, zone_code)
  select distinct market_code, market_name, upper(zone)
  from transactions;

Customers

create table customer
(
  customer_code varchar(100) not null,
  market_code varchar(100) not null,
  primary key (customer_code),
  constraint fk_customer_market foreign key(market_code) references market(market_code)
);

insert into customer (customer_code, market_code)
  select distinct customer_code, market_code
  from transactions;

Transactions

Remove the now redundant columns from the table. They are now implicit with the customer.

alter table transactions
  drop column market_code,
  drop column market_name,
  drop column zone;
病毒体 2025-02-17 18:26:36

根据我的理解,您只需要一个独特的条款 -

CREATE TABLE customers as
SELECT DISTINCT customer_code, market_code, market_name, zone 
  FROM transactions;

As per my understanding, You simply need a DISTINCT clause -

CREATE TABLE customers as
SELECT DISTINCT customer_code, market_code, market_name, zone 
  FROM transactions;
葮薆情 2025-02-17 18:26:36

如果您尝试从SELECT CUSTROR_CODE,MARKET_CODE,MARKET_NAME,ZORE创建临时表,该怎么办?然后从临时表中尝试进行独特的组。

What if you try to create temporary table from select customer_code, market_code, market_name, zone? Then from the temp table try to do the distinct and group by.

岁吢 2025-02-17 18:26:36

为了使customer_code字段在此表中具有唯一的值,例如,对于同一customer_code的事务表中的其他字段不能具有不同的值区域字段,在交易表的不同行中,因此需要采用您尚未考虑的聚类策略。

小组按子句需要一些汇总函数,例如sum,max,min,avg等...在MySQL中,当您不使用任何一个函数时,它会带来第一行,从而确保组的分组。在postgresql中,这不会发生,在未分组的字段上需要聚集功能。

在下面,我举例说明了如何在不创建视图或其他内容的情况下分解表格,这使您的问题等复杂问题变得更加容易。也许如果您在问题中更具体,那么给出更好的答案会更容易。

CREATE TABLE customers AS 
WITH STEP_A AS (
    SELECT 
        T.customer_code
        , COUNT(T.customer_code) AS TOT
    FROM
        transactions T 
    GROUP BY
        T.customer_code 
)
, STEP_B AS (
    SELECT 
        A.customer_code 
    FROM
        STEP_A A
    INNER JOIN 
        transactions T 
        ON A.customer_code = T.customer_code 
    WHERE 
        A.TOT = 1
)

SELECT 
    B.* 
FROM 
    STEP_B B 
ORDER BY
    B.customer_code ASC
;

希望这会有所帮助!!祝你好运!

In order for the customer_code field to have unique values ​​in this table, the other fields cannot have different values ​​in the transactions table for the same customer_code, for example, if it is possible for a customer_code to have different values ​​in the market_code, market_name or zone fields, in different rows of the transactions table so this calls for a clustering strategy that you haven't considered.

The GROUP BY clause requires some aggregation function like SUM, MAX, MIN, AVG, etc... in MySQL when you don't use any of that it brings the first row found ensuring the grouping of what was requested in the GROUP BY , in PostgreSQL this does not happen, the aggregation function is required on ungrouped fields.

Below I give an example of how to work breaking up tables without creating views or something else, which makes it easier for complex issues like your question. Maybe if you are more specific in the question it will be easier to give a better answer.

CREATE TABLE customers AS 
WITH STEP_A AS (
    SELECT 
        T.customer_code
        , COUNT(T.customer_code) AS TOT
    FROM
        transactions T 
    GROUP BY
        T.customer_code 
)
, STEP_B AS (
    SELECT 
        A.customer_code 
    FROM
        STEP_A A
    INNER JOIN 
        transactions T 
        ON A.customer_code = T.customer_code 
    WHERE 
        A.TOT = 1
)

SELECT 
    B.* 
FROM 
    STEP_B B 
ORDER BY
    B.customer_code ASC
;

Hope this helps!! Good luck!

少女净妖师 2025-02-17 18:26:36

嗨,在查询中添加不同的列,并将所有列分组,然后将其保存为CSV。
PostgreSQL稍后导入CSV。

    SELECT DISTINCT 
       customer_code -- 1
      ,market_code   -- 2
      ,market_name   -- 3
      ,zone          -- 4

   FROM transactions 
   GROUP by 1,2,3,4

Hi add DISTINCT in your Query and group all columns and save this as csv.
PostgreSQL Import CSV later.

    SELECT DISTINCT 
       customer_code -- 1
      ,market_code   -- 2
      ,market_name   -- 3
      ,zone          -- 4

   FROM transactions 
   GROUP by 1,2,3,4
呆萌少年 2025-02-17 18:26:36

下表创建名称客户的表

with cte as(
  select customer_code from transactions
    group by customer_code
  )select * into customers from cte

following table create table with name Customers

with cte as(
  select customer_code from transactions
    group by customer_code
  )select * into customers from cte
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文