Crystal Report do not do the sum on Database "Cache" - database

I am using Crystal report to do a sum over 3 columns. The table structure looks like:
table #test (Country VARCHAR(10), Name VARCHAR(10), Weight VARCHAR(10), Qty INT)
I wrote a query in the crystal command pane when I do the connection:
SELECT Country, SUM(Qty) As Qty, Name, Weight FROM #test GROUP BY Country, Name, Weight
I should get something like:
CANADA 2 John 200
US 1 John 160
US 2 Mike 180
US 6 Sam 90
However, the crystal report does not sum the field, instead it pulls every single row, and the result looks like I write the query:
SELECT Country, Qty, Name, Weight FROM #test
CANADA 1 John 200
CANADA 1 John 200
US 1 John 160
US 2 Mike 180
US 3 Sam 90
US 3 Sam 90
By the way, the backend database is called "Cache". It might be due to there are some hidden characters, but I cannot see them. I have used replace (char(10)), replace (char(13) and trim to try to clean.
I also try to pull the table column directly without writing the query, but I do not know how to sum three columns (Country, Name and Weight). I only know how to sum one column. By the way, the request do not want the details, only the sum over these three columns;

First group by country.
Create one more group by quantity
Create one more group by name
Place weight in details and take the sum for all 3 groups if you need or only particular group
Supress tje details.

Related

How to manage multiple currencies in the database

If I have different multiple payroll disbursements based on the company location, the employee contract type and other criteria:
So
Some have their salaries divided into parts the first in USD and the second in Local cur.
Ex: Employee 343 receive his salary as following: 200 USD & 3000 EGP (The local currency).
EX: Employee 672 receive his salary as following: 200 USD & 200 EUR (The local currency).
Some have their salaries just in one currency (the local).
Ex: Employee 532 receive his salary as following: 5000 EGP.
So We have multiple currencies for the salaries of the company based on the location and other business rules.
What 's the most proper way to save the salaries of the employees with these variations in DB so that It's easy to retrieve, process and scale.
If I use one table so I will have many columns and I have to add new columns every time a new branch for the company is initiated.
Like this:
Sal_USD | Sal_EGP | Sal_Eur
Is there an elegant way to handle this?
The correct way is always to support an infinite numbers of connections. So create a table with salary an another with currency.
I think 3tables would do the jobb
Employee (the one you have now)
- EmployeeID
Salary
- SalaryID
- EmployeeID
- CurrencyID
- Wage
- Exchangerate ?
CurrencyID
- CurrencyID
- Name (USD/GDP/EUR....)
Then you simply join them in.
Create a column CurrencyCode and use 2 rows for an employee that has salary paid in 2 currencies.

SSIS - Merging rows with aggregate determinations

I'm attempting to determine the best way, either in SSIS or straight TSQL, to merge two rows based on a given key, but taking specific data from each row based on various aggregate rules (MAX and SUM specifically). As an example, given the following dataset:
Customer Name Total Date Outstanding
12345 A 100 7/15/2015 500
12345 200 1/1/2015 300
456 B 500 1/2/2010 100
456 B 250 2/1/2015 900
78 C 100 9/15/2015 500
I wish to consolidate those to a single row per customer key, with the following rules as an example:
If any name is null, use a corresponding value for that customer that is not null
MAX(Total)
MAX(Date)
SUM(Outstanding)
The result set would be:
Customer Name Total Date Outstanding
12345 A 200 7/15/2015 800
456 B 500 2/1/2015 1000
78 C 100 9/15/2015 500
What's the best approach here? My first instinct is to query the table to join to itself on customer to get all values on a single row, and then use formulas in a Derived Column task in SSIS to determine the values to use. My concern there is that is not scalable - it works fine if I have a customer occur only twice in the main dataset, but the goal would be for the logic to work for N number of rows without needing to do a ton of rework. I'm sure there's also a TSQL approach that I'm missing here. Any help would be appreciated.
If name column in your query is not empty then you can do that simply by using aggregate function in one query
DECLARE #Customer TABLE
(
Customer INT, Name varchar(10), Total INT , PurchaseDate DATE , Outstanding INT
)
INSERT INTO #Customer
SELECT 12345,'A',100,'7/15/2015',500 UNION
SELECT 12345,'A',200,'1/1/2015',300 UNION
SELECT 456,'B',500,'1/2/2010',100 UNION
SELECT 456,'B',250,'2/1/2015',900 UNION
SELECT 78,'C',100,'9/15/2015',500
SELECT Customer,NAME ,MAX(Total), MAX(PurchaseDate), SUM(outstanding)
FROM #Customer
GROUP BY Customer, NAME
Demo
Now, if your name column is empty in few cases like you have mentioned in your example then you can update name table with correct name value

RANKX not working when data summarized in power pivot table

I am trying to rank records in power pivot table using DAX as below in MSSQL analysis service tabular model.
Example details:
I have a shop sales detail in table.
e.g.
ShopNo date sales
-----------------
1 2014-11-09 120
1 2014-11-09 130
2 2014-11-10 130
2 2014-11-10 135
In pivot table data is analyzed month and year wise.
I want to see result like
ShopNo sales rank
-----------------
2 265 1
3 250 2
Any solution is there to display statewise population automatically.
Thanks
You should be able to achieve the ranking quite easily with PowerPivot using this formula:
RankShop:=RANKX(ALL(SalesTable[ShopNo]), [Sum of sales],,,Dense)
With SalesTable being your shops sales table. If you then create a pivot table - drag ShopNo onto Rows and add new Measure (Excel 2010, in 2013 it's Calculated Field). The resulting table could then look like this:
To find out more about RANK function, I suggest this article.
In order to hide the rank value in Grand Total row, add a simple condition that puts blank values in case of grandtotals:
=IF(HASONEVALUE(SalesTable[ShopNo]), [RankShop], BLANK())
Hope this helps.

sql server sum column to find out who reached a value first

I asked a question similar to this here:
sql sum a column and also return the last time stamp
It turns out my use case was incorrect though so I need to make an adjustment to my question.
I've got a table in SQL Server with several columns. The relevant ones are:
name
distance
create_date
I have many people identified by name, and every few days they travel a certain distance. For example:
name distance create_date
john 15 09/12/2014
john 20 09/22/2014
alex 10 08/15/2014
alex 12 09/05/2014
alex 20 09/12/2014
john 8 09/30/2014
alex 30 09/14/2014
mike 12 09/10/2014
The query I need has 3 parameters:
#start_date
#end_date
#count
I need a query that between the two dates, returns for each person the distance traveled. The trick though is that for each person I should sum to an amount just past the amount indicated in #count and return the date this was achieved, or if the person did not pass the #count then return the sum and last date of entry. So for example, if I use the parameters:
#start_date=08/01/2014
#end_date=09/25/2014
#count=35
I would expect the following:
name distance create_date
alex 42 09/12/2014
john 35 09/22/2014
mike 12 09/10/2014
Does someone have an idea for this?
Thank you!
As per my understanding the query for the the person who crossed particular count
select A.name,sum(A.distance),A.create_date from (select name,distance,create_date
from table where create_date between #start_date and #end_date)A group by A.name,A.create_date
having sum(A.distance)>#count
Those who doesnt cross
select A.name,sum(A.distance),max(A.create_date) from (select name,distance,create_date
from table where create_date between #start_date and #end_date)A group by A.name
having sum(A.distance)<#count

SQL Server 2008 View Group By

I have created the following view in SQL Server 2008 to create mailing lists for land owners:
SELECT
dbo.parcel.featid,
CAST(mms_db.dbo.TR_Roll_Master.FMT_ROLL_NO AS decimal(11, 3)) AS Roll,
dbo.parcel.survey, mms_db.dbo.Central_Name_Database.NAME AS Owner,
mms_db.dbo.Central_Name_Database.NAME_2 AS Owner2,
mms_db.dbo.Central_Name_Database.BOX_NUM,
mms_db.dbo.Central_Name_Database.APT_NUM,
mms_db.dbo.Central_Name_Database.FMT_STREET AS House_num,
mms_db.dbo.Central_Name_Database.CITY AS Town,
mms_db.dbo.Central_Name_Database.PROV_CD AS Prov,
mms_db.dbo.Central_Name_Database.POST_CD AS Post_code,
mms_db.dbo.TR_Roll_Number_Owners.NAME_CODE
FROM
mms_db.dbo.TR_Roll_Master
INNER JOIN
dbo.parcel ON mms_db.dbo.TR_Roll_Master.ROLL_NO = dbo.parcel.roll_no COLLATE SQL_Latin1_General_CP1_CI_AS
INNER JOIN
mms_db.dbo.TR_Roll_Number_Owners ON mms_db.dbo.TR_Roll_Master.ROLL_NO = mms_db.dbo.TR_Roll_Number_Owners.ROLL_NO
INNER JOIN
mms_db.dbo.Central_Name_Database ON mms_db.dbo.TR_Roll_Number_Owners.NAME_CODE = mms_db.dbo.Central_Name_Database.NAME_CODE
WHERE
(mms_db.dbo.TR_Roll_Master.DEL_ROLL NOT LIKE '%Y%') AND
(mms_db.dbo.TR_Roll_Master.ROLL_NO NOT LIKE 'P%') OR
(mms_db.dbo.TR_Roll_Master.DEL_ROLL IS NULL) AND (mms_db.dbo.TR_Roll_Master.ROLL_NO NOT LIKE 'P%') OR
(mms_db.dbo.TR_Roll_Master.DEL_ROLL NOT LIKE '%I%') AND
(mms_db.dbo.TR_Roll_Master.ROLL_NO NOT LIKE 'P%')
The view works fine however there are often duplicates as many people own more than one piece of land. I would like to group by Name_Code to eliminate the duplicates.
When I add:
Group by mms_db.dbo.TR_Roll_Number_Owners.NAME_CODE
to the end of the query I am returned with the following response:
SQL Execution Error.
Executed SQL statement: SELECT dbo.parcel.featid, CAST(mms_db.dbo.TR_Roll_Master.FMT_ROLL_NO AS decimal(11,3)) AS Roll,
dbo.parcel.survey,
mms_db.dbo.Central_NameDatabase.Name AS Owner,
mms_db.dbo.Central_Name_Database.NAME_2 AS Owner2,
mms_db.dbo.Central_Name_Database.B...
Error Source: .Net SQLClient Data Provider
Error Message: Column 'dbo.parcel.featid' is invalid in the select list
because it is not contained in either an aggregate function or the
GROUP BY clause.
I'm not sure what I need to change to make this work.
--Edit--
As a sample data, here is a condensed sample of what I would like to achieve
Roll Owner Box_Num Town Prov Post_code Name_Code
100 John Smith 50 Somewhere MB R3W 9T7 00478
200 John Smith 50 Somewhere MB R3W 9T7 00478
300 Peter Smith 72 Somewhere MB R3W 9T9 00592
400 John Smith 90 OtherPlace MB R2R 8V7 00682
John Smith has the name code of 00478. He owns both Roll 100 & 200, Peter Smith owns 300 and another person with the name of John Smith owns 400. Based on different Name_Code values I know that the two John Smith's are different people. I would like an output that would list John Smith with Name_Code 00478 1 time only while also listing Peter Smith and the other John Smith. Name_Code is the only value I can use for grouping as the rest could represent different people with the same name.
If you just want to eliminate duplicates, just use DISTINCT and exclude the columns representing other "people on more than one piece of land" from your query viz:
SELECT DISTINCT
NAME_CODE,
{column2},
{column3},
FROM
[MyView]
However, if you wish to perform aggregation of some sort, or show one random of the "people on more than one piece of land" then you will need the GROUP BY. All non-aggregated columns in the select need to appear in the group by:
SELECT
NAME_CODE,
... Other non aggregated fields here
COUNT(featid) AS NumFeatIds,
MIN(Owner2) AS FirstOwner,
... etc (other aggregated columns)
GROUP BY
NAME_CODE,
... All non-aggregated columns in the select.
Edit
To get the table listed in your edit, you would just need to ORDER BY Name_Code
However to get just one row of John Smith #00478, you need to compromise on the non-unique columns by either eliminating them entirely, using GROUP BY and aggregates on the rows, doing a GROUP_CONCAT type hack to e.g. comma separate them, or to pivot the duplicate row columns as extra columns on the one row.
Since you've mentioned GROUP repeatedly, it seems the aggregation route is necessary. John Smith #00478 has 2 properties, hence 2 discrete Roll values. So Roll can't appear in the aggregated result. So instead, you can return e.g. a count of the Rolls, or the MIN or MAX Roll, but not both Rows*. The other columns (Address related) are probably constant for all properties (assuming John Smith 00478 has one address), but unfortunately SqlServer will require you to include them in the GROUP.
I would suggest you try:
SELECT
COUNT(Roll) AS NumPropertiesOwned,
Owner,
Box_Num,
Town,
Prov,
Post_code,
Name_Code
FROM [MyNewView]
GROUP BY
Owner, Box_Num, Town, Prov, Post_code, Name_Code
ORDER BY Name_Code;
i.e. all the non-aggregated columns must be repeated in the GROUP BY
* unless you use the GROUP_CONCAT hack or the pivot route
its telling you what to do:
"Error Message: Column 'dbo.parcel.featid' is invalid in the select list
because it is not contained in either an aggregate function or the
GROUP BY clause."
This means you have to group the other (non-aggregated) fields too.

Resources