Showing posts with label customer. Show all posts
Showing posts with label customer. Show all posts

Wednesday, March 28, 2012

Query - SUM multi-column

I use a query to get customer unpaid amount into different colomns according to due day as the following:

Select c.credit_controller,c.customer,c.name,i.unall_amount,
CASE /*cash due*/
when i.kind='CSH' then i.unall_amount
else 0
end as amtcash,
CASE /*sales_item.due_date - today < 0 */
WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate()) < 0)
THEN i.unall_amount
ELSE 0
END AS amtcur,
CASE /*sales_item.due_date - today > 0 & <= 30*/
WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())
BETWEEN 0 AND 30) THEN i.unall_amount
ELSE 0
END AS amt30,
CASE /*sales_item.due_date - today > 30 & <= 60*/
WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())
BETWEEN 31 AND 60) THEN i.unall_amount
ELSE 0
END AS amt60,
CASE /*sales_item.due_date - today > 60 & <= 90*/
WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())
BETWEEN 61 AND 90) THEN i.unall_amount
ELSE 0
END AS amt90,
CASE /*sales_item.due_date - today > 90*/
WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())
> 90) THEN i.unall_amount
ELSE 0
END AS amt120,
c.analysis_codes
From scheme.slcustm c INNER JOIN scheme.slitemm i ON c.customer=i.customer

I want to SUM those records and GROUP BY c.credit_controller & c.customer in a SELECT query.

If I use SUM(i.unall_amount) instead of i.unall_amount, there're errors as the following:

Column 'c.cusomter' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Column 'i.kind' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Column c.analaysis_code' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

How to SUM in this query?

Thanks!

yabing


When you use GROUP BY statetment, then any column used in select list must be also GROUP BY list or under some aggregation function.

So if you want GROUP BY by c.credit_controller, c.customer you also need include c.name into GROUP BY, then use SUM(i.unall_amount) and SUM() around each CASE statement:

Code Snippet

Select c.credit_controller,c.customer,c.name, SUM(i.unall_amount),

SUM( CASE /*cash due*/

when i.kind='CSH' then i.unall_amount

else 0

end) as amtcash,

SUM( CASE /*sales_item.due_date - today < 0 */

WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate()) < 0)

THEN i.unall_amount

ELSE 0

END )AS amtcur,

SUM( CASE /*sales_item.due_date - today > 0 & <= 30*/

WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())

BETWEEN 0 AND 30) THEN i.unall_amount

ELSE 0

END )AS amt30,

SUM( CASE /*sales_item.due_date - today > 30 & <= 60*/

WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())

BETWEEN 31 AND 60) THEN i.unall_amount

ELSE 0

END )AS amt60,

SUM( CASE /*sales_item.due_date - today > 60 & <= 90*/

WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())

BETWEEN 61 AND 90) THEN i.unall_amount

ELSE 0

END )AS amt90,

SUM( CASE /*sales_item.due_date - today > 90*/

WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())

> 90) THEN i.unall_amount

ELSE 0

END ) AS amt120

From scheme.slcustm c INNER JOIN scheme.slitemm i ON c.customer=i.customer

GROUP BY c.credit_controller,c.customer,c.name

|||

Hi Konstantin,

Thanks for your replay. It works.

I understand "When you use GROUP BY statetment, then any column used in select list must be also GROUP BY list or under some aggregation function." But I only want to group value by two columns - c.credit_controller and c.customer, not c.name and c.analysis_codes. When using "GROUP BY c.credit_controller,c.customer,c.name,c.analysis_codes", how it groups columns? does it group the columns one by one for all the four columns in the list in the GROUP BY clause? does it aggregate values for everty possible combination of the columns in the GROUP BY clause?

Though it seems it doesn't group that way when testing. But why?

Thanks,

yabing

|||

If you use "GROUP BY c.credit_controller,c.customer,c.name,c.analysis_codes" its group and aggregate for every possible combinations. So if you have few different values of c.name,c.analysis_codes for each unique pair of c.credit_controller,c.customer you will get additional lines.

But for example if you have following values:

c.credit_controller c.customer c.name

1 1 A

1 1 B

and use GROUP BY c.credit_controller,c.customer plus c.name in SELECT list. What do you want see in your result set? A or B?

You must include c.name in aggregation. For example you could use MIN or MAX or (if you have SQL Server 2005) write you own User-Defined Aggregate.This UDAG could concat values or do something else.

|||

Dear Konstantin.

I have one question of GROUP BY,

When I use GROUP BY and use SUM around each CASE statement, it take very long query time.

Can we set a condition eg, query for c.name='A' only?

Thanks

pps1

|||You could write WHERE for filtering. GROUP BY works after WHERE

Query - SUM multi-column

I use a query to get customer unpaid amount into different colomns according to due day as the following:

Select c.credit_controller,c.customer,c.name,i.unall_amount,
CASE /*cash due*/
when i.kind='CSH' then i.unall_amount
else 0
end as amtcash,
CASE /*sales_item.due_date - today < 0 */
WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate()) < 0)
THEN i.unall_amount
ELSE 0
END AS amtcur,
CASE /*sales_item.due_date - today > 0 & <= 30*/
WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())
BETWEEN 0 AND 30) THEN i.unall_amount
ELSE 0
END AS amt30,
CASE /*sales_item.due_date - today > 30 & <= 60*/
WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())
BETWEEN 31 AND 60) THEN i.unall_amount
ELSE 0
END AS amt60,
CASE /*sales_item.due_date - today > 60 & <= 90*/
WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())
BETWEEN 61 AND 90) THEN i.unall_amount
ELSE 0
END AS amt90,
CASE /*sales_item.due_date - today > 90*/
WHEN (i.kind='INV' OR i.kind='CRN') AND (DATEDIFF (day, i.due_date, getdate())
> 90) THEN i.unall_amount
ELSE 0
END AS amt120,
c.analysis_codes
From scheme.slcustm c INNER JOIN scheme.slitemm i ON c.customer=i.customer

I want to SUM those records and GROUP BY c.credit_controller & c.customer in a SELECT query.

If I use SUM(i.unall_amount) instead of i.unall_amount, there're errors as the following:

Column 'c.cusomter' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Column 'i.kind' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Column c.analaysis_code' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

How to SUM in this query?

Thanks!

yabing


When you use GROUP BY statetment, then any column used in select list must be also GROUP BY list or under some aggregation function.

So if you want GROUP BY by c.credit_controller, c.customer you also need include c.name into GROUP BY, then use SUM(i.unall_amount) and SUM() around each CASE statement:

Code Snippet

Select c.credit_controller,c.customer,c.name,SUM(i.unall_amount),

SUM(CASE/*cash due*/

when i.kind='CSH'then i.unall_amount

else 0

end)as amtcash,

SUM(CASE/*sales_item.due_date - today < 0 */

WHEN(i.kind='INV'OR i.kind='CRN')AND(DATEDIFF(day, i.due_date,getdate())< 0)

THEN i.unall_amount

ELSE 0

END)AS amtcur,

SUM(CASE/*sales_item.due_date - today > 0 & <= 30*/

WHEN(i.kind='INV'OR i.kind='CRN')AND(DATEDIFF(day, i.due_date,getdate())

BETWEEN 0 AND 30)THEN i.unall_amount

ELSE 0

END)AS amt30,

SUM(CASE/*sales_item.due_date - today > 30 & <= 60*/

WHEN(i.kind='INV'OR i.kind='CRN')AND(DATEDIFF(day, i.due_date,getdate())

BETWEEN 31 AND 60)THEN i.unall_amount

ELSE 0

END)AS amt60,

SUM(CASE/*sales_item.due_date - today > 60 & <= 90*/

WHEN(i.kind='INV'OR i.kind='CRN')AND(DATEDIFF(day, i.due_date,getdate())

BETWEEN 61 AND 90)THEN i.unall_amount

ELSE 0

END)AS amt90,

SUM(CASE/*sales_item.due_date - today > 90*/

WHEN(i.kind='INV'OR i.kind='CRN')AND(DATEDIFF(day, i.due_date,getdate())

> 90)THEN i.unall_amount

ELSE 0

END)AS amt120

From scheme.slcustm c INNERJOIN scheme.slitemm i ON c.customer=i.customer

GROUPBY c.credit_controller,c.customer,c.name

|||

Hi Konstantin,

Thanks for your replay. It works.

I understand "When you use GROUP BY statetment, then any column used in select list must be also GROUP BY list or under some aggregation function." But I only want to group value by two columns - c.credit_controller and c.customer, not c.name and c.analysis_codes. When using "GROUP BY c.credit_controller,c.customer,c.name,c.analysis_codes", how it groups columns? does it group the columns one by one for all the four columns in the list in the GROUP BY clause? does it aggregate values for everty possible combination of the columns in the GROUP BY clause?

Though it seems it doesn't group that way when testing. But why?

Thanks,

yabing

|||

If you use "GROUP BY c.credit_controller,c.customer,c.name,c.analysis_codes" its group and aggregate for every possible combinations. So if you have few different values of c.name,c.analysis_codes for each unique pair of c.credit_controller,c.customer you will get additional lines.

But for example if you have following values:

c.credit_controller c.customerc.name

1 1 A

1 1 B

and use GROUP BY c.credit_controller,c.customer plus c.name in SELECT list. What do you want see in your result set? A or B?

You must include c.name in aggregation. For example you could use MIN or MAX or (if you have SQL Server 2005) write you own User-Defined Aggregate.This UDAG could concat values or do something else.

|||

Dear Konstantin.

I have one question of GROUP BY,

When I use GROUP BY and use SUM around each CASE statement, it take very long query time.

Can we set a condition eg, query for c.name='A' only?

Thanks

pps1

|||You could write WHERE for filtering. GROUP BY works after WHERE

Monday, March 26, 2012

query

Hi, how to write a query can group customer sale by month? please help.js wrote:
> Hi, how to write a query can group customer sale by month? please
> help.
www.aspfaq.com/5006
--
Microsoft MVP -- ASP/ASP.NET
Please reply to the newsgroup. The email account listed in my From
header is my spam trap, so I don't check it very often. You will get a
quicker response by posting to the newsgroup.|||Try,
use northwind
go
select
c.customerid,
year(oh.orderdate) as col_year,
month(oh.orderdate) as col_month,
sum(od.Quantity * (cast((1.00 - od.Discount) as money) * od.UnitPrice))
from
customers as c
inner join
orders as oh
on c.customerid = oh.customerid
inner join
[order details] as od
on oh.orderid = od.orderid
group by
c.customerid,
year(oh.orderdate),
month(oh.orderdate)
order by
c.customerid,
col_year,
col_month
go
-- or
select
c.customerid,
convert(char(6), oh.orderdate, 112) as col_yyyymm,
sum(od.Quantity * (cast((1.00 - od.Discount) as money) * od.UnitPrice))
from
customers as c
inner join
orders as oh
on c.customerid = oh.customerid
inner join
[order details] as od
on oh.orderid = od.orderid
group by
c.customerid,
convert(char(6), oh.orderdate, 112)
order by
c.customerid,
col_yyyymm,
go
AMB
"js" wrote:

> Hi, how to write a query can group customer sale by month? please help.
>
>|||SELECT Count(*), SUM(st.SalesAmount), Month(st.SalesDateField),
Year(st.SalesDateField)
FROM SalesTable st
--WHERE st.CustomerID = 1234
GROUP BY Month(st.SalesDateField), Year(st.SalesDateField)
"js" <js@.someone@.hotmail.com> wrote in message
news:er7mNsxAFHA.3940@.TK2MSFTNGP09.phx.gbl...
> Hi, how to write a query can group customer sale by month? please help.
>
>|||Thanks all,
Can I force it to output as follow(even 1997, Feb doesn't have data):
1997 1 503.5000
1997 2
1997 3 340.0000
1997 4
1997 5 340.0000
1997 6
"David Buchanan" <dbuch328@.cox.net> wrote in message
news:RfyJd.23223$EG1.4463@.lakeread04...
> SELECT Count(*), SUM(st.SalesAmount), Month(st.SalesDateField),
> Year(st.SalesDateField)
> FROM SalesTable st
> --WHERE st.CustomerID = 1234
> GROUP BY Month(st.SalesDateField), Year(st.SalesDateField)
> "js" <js@.someone@.hotmail.com> wrote in message
> news:er7mNsxAFHA.3940@.TK2MSFTNGP09.phx.gbl...
>|||Try,
use northwind
go
select
c.customerid,
p.col_year,
p.col_month,
sum(od.Quantity * (cast((1.00 - od.Discount) as money) * od.UnitPrice)) as
sales
from
customers as c
cross join
(
select
*
from
(
select distinct year(orderdate) from orders
) as y(col_year)
cross join
(
select 1
union all
select 2
union all
select 3
union all
select 4
union all
select 5
union all
select 6
union all
select 7
union all
select 8
union all
select 9
union all
select 10
union all
select 11
union all
select 12
) as m(col_month)
) as p(col_year, col_month)
left join
orders as oh
on c.customerid = oh.customerid and year(oh.orderdate) = p.col_year and
month(orderdate) = p.col_month
left join
[order details] as od
on oh.orderid = od.orderid
where
c.customerid = 'alfki'
group by
c.customerid,
p.col_year,
p.col_month
order by
c.customerid,
p.col_year,
p.col_month
go
AMB
"js" wrote:

> Thanks all,
> Can I force it to output as follow(even 1997, Feb doesn't have data):
> 1997 1 503.5000
> 1997 2
> 1997 3 340.0000
> 1997 4
> 1997 5 340.0000
> 1997 6
>
> "David Buchanan" <dbuch328@.cox.net> wrote in message
> news:RfyJd.23223$EG1.4463@.lakeread04...
>
>|||Thanks Alejandro...
"Alejandro Mesa" <AlejandroMesa@.discussions.microsoft.com> wrote in message
news:706A502C-6657-4F00-BA5F-3B3A4B7E295C@.microsoft.com...
> Try,
> use northwind
> go
> select
> c.customerid,
> p.col_year,
> p.col_month,
> sum(od.Quantity * (cast((1.00 - od.Discount) as money) * od.UnitPrice)) as
> sales
> from
> customers as c
> cross join
> (
> select
> *
> from
> (
> select distinct year(orderdate) from orders
> ) as y(col_year)
> cross join
> (
> select 1
> union all
> select 2
> union all
> select 3
> union all
> select 4
> union all
> select 5
> union all
> select 6
> union all
> select 7
> union all
> select 8
> union all
> select 9
> union all
> select 10
> union all
> select 11
> union all
> select 12
> ) as m(col_month)
> ) as p(col_year, col_month)
> left join
> orders as oh
> on c.customerid = oh.customerid and year(oh.orderdate) = p.col_year and
> month(orderdate) = p.col_month
> left join
> [order details] as od
> on oh.orderid = od.orderid
> where
> c.customerid = 'alfki'
> group by
> c.customerid,
> p.col_year,
> p.col_month
> order by
> c.customerid,
> p.col_year,
> p.col_month
> go
>
> AMB

Query

I have attached the Adventureworks database to SQL Server 2005.

Whenerver I try to run a new query to this database

Ex: select * from sales.customer

I get this error message

Msg 208, Level 16, State 1, Line 1

Invalid object name 'sales.customer'.

I don't know why this is happining?

Hi,

make sure you are deling with the right database (Select db_name()).

Didi you change the default collation ? Seems that you are using a CS Coallation, that means that its case sensity, you can check that by using the query:

SELECT databasepropertyex('Adventureworks','collation')

Select * from Sales.Customer

So I guess, if you *are* connected to the right database, you should be fine using the proper typing of the name (otherwise, if you are feeling not comfortable withthis solution, you could change the collation of the database, by using the statemetn ALTER DATABSE, look in the BOL for more information)

HTH, Jens Suessmeyer.

http://www.sqlserver2005.de

|||Thanks a lot Jenssql

Monday, March 12, 2012

Qualify customer information

Can anyone advise me of how to make sure that a customer is inputting
correct information into the database.
I am building a website, where customers are not logging in, but request
info. by name, addr. and postcode/city, email. I want to check if the
customer exists in the database or not.
Who has any knowledge of this i.e. validating customer name, addr. etc.
information. Which search technics in SQL Server should I make use of (i.e.
should I search exact match with addr. and name, or only with email, are
there any other searching technics to make use of ?).
Your post contains several broad questions which cannot be aptly answered
without more specifics. In general, when customer information is recorded in
a database uniquely, one can use a simple IF EXISTS() check to see if a
specific row exists in a table. For instance:
IF EXISTS ( SELECT * FROM tbl WHERE keycol = @.someval )
-- Data exists
ELSE
-- Data does not exist
Depending on what attributes ( like name, address, email etc. ) make up a
unique customer in your table, you may have to make use of a proper
predicate which can identify the row.
Anith