cakephp - view with data from multiple tables as one - cakephp

I want to have a view for each table (letters, filings, notes) which each have a name and date. I want to have a separate view for items from each table that also fall into a particular category -- say categoryx -- so it is a separate view. The categoryx view would combine particular fields from each of the multiple tables into one table, in effect, ordered by date.
E.g.,
Category x
DATE NAME ORIGTABLE
1/2/11 SmithToJones Letters
1/3/11 Filing on X Filings
1/4/11 Note re X Notes
1/7/11 JonesToSmith Letters
I'm just stumped on whether there is a good or straightforward way to do this. Open to options. Thanks

I think I have the answer, though it's not perfect. I do this in the controller (may try it in the model next):
$query='select name,date, "letters" as "origtable" from letters
UNION SELECT name,date, "filings" as "origtable" from filings
UNION SELECT name,date, "notes" as "origtable" from notes
ORDER BY date';
$things=$this->Letter->query($query);
$this->set('items',$things);
This gets me an array I can parse out. If I add id to it, then I can easily create links to the relevant item in the relevant table.

Related

Identify elements that do not appear in the period (Google Data Studio)

I have a table that shows the recurrence of purchasing a product, with the columns: product_id, report_date, quantity.
I need to list in a table the products that are more than 50 days unsold. The opposite I managed to do (list those that were sold in the last 50 days) but the opposite logic has not yet been able to implement.
Does anyone have any tips?
An example of the table:
product_id,date,report_date,quantity
329,2019-01-02 08:19:17,2019-01-02 14:34:12,6
243,2019-01-03 09:19:17,2019-01-03 15:34:12,6
238,2019-02-02 08:19:17,2019-03-02 14:34:12,84
170,2019-04-02 08:19:17,2019-04-02 14:34:12,84
238,2019-04-02 08:19:17,2019-04-02 14:34:12,8
238,2019-04-02 08:19:17,2019-04-02 14:34:12,100
238,2019-08-02 08:19:17,2019-08-02 14:34:12,100
238,2019-10-02 08:19:17,2019-10-02 14:34:12,100
170,2020-01-02 08:19:17,2020-01-02 14:34:12,84
170,2020-01-02 08:19:17,2020-01-02 14:34:12,84
There are many steps to do this task. I assume the date column is the one to work with. Your example from table includes duplicated entries. Is it right that at the same time the order is there twice?
So here are the steps:
At first add an calculated field date_past to your dataset:
DATE_DIFF(CURRENT_DATE(),date)
To the dataset add a filter SO_demo with:
include date_past<30
Then blend the data with it self. Use product_id as Join key. Only the 2nd dataset has the SO_demo filter. Add to the dimension of this dataset the calculated field sold_last_30_days with the formula "yes".
In the table/chart to display add a filter on the field include sold_last_30_days is Null.

Strategy to design specification table for measurements data for analytical database project

I need advice on the following topic:
I am developing a DW/BI solution in SQL Server and reports are published in Power BI.
Main part of my question starts here: I have a large table which collects measurement data on product measurement for multiple attributes. Product can be of multiple type, that can be recognised by item number in this table, measurements can be done multiple times and can be identified by measurement date. Usually, we refer latest dates. If it makes things complicated, I can filter data for latest dates only. This is dense row table (multi million). Number of attribute counts about 200.
I want to include specifications for these attributes most likely in a dimension table, and there may be tens of such specifications. Intention is that user shall select in the report any one specification name and he would like to see each product with attributes passing/failing as well as the products passing if all all of specification attributes are passed.
I currently have this measurement table and a dim table with test names, I can add a table for specification if needed. Specification can define few or all test names with lower/upper spec limits:
Sample measurement table:
Sample dim table for test names:
I can add a table for specification as below and user will select any of one:
e.g. Use select ID_spec = 1 then measurement table may look like:
Some spec may contain all and some few attributes.
Please suggest strategy to design a spec table to be efficient for such large size tables. Please let me know if any further details needed.
Later, I will have to further work to calculate % of pass product if they have been tested for all needed tests in a specification selected.
For large tables, the best thing to do is choose the right key. That means dumping the "Id" column (nothing more than a row identifier) and replacing it with something that:
Guarantees uniqueness
Facilitates searches
That often means composite keys, which are fine.
It's also means dumping the whole "fact/dimension" mindset and just focusing on the relations. This is also fine.
Based on your description, this is the first draft of a data model for your warehouse. If you are unfamiliar with IDEF1X diagrams, please read this.
I've added a unique constraint to SpecCd so you could specify the value directly instead of having to check both the ProductId and SpecCd to return a result.
ProductTest exists so you can provide integrity for ProductTestCriteria and ensure tests are limited to only those products that can be measured by them. If all products are subject to all tests, this can be removed and Test can relate directly to ProductMeasurement and ProductTestCriteria.
If you want to subject the latest test of "Product A" to "Spec S" your query would look like:
SELECT
Measurement.ProductId
,Measurement.TestCd
,Measurement.TestDt
,Criteria.SpecCd
,Measurement.Value
,CASE
WHEN Measurement.Value BETWEEN Criteria.LowerValue AND Criteria.UpperValue THEN 'Pass'
ELSE 'Fail'
END AS Result
FROM
ProductMeasurement Measurement
INNER JOIN
ProductTestCriteria Criteria
ON Critera.ProductId = Measurement.ProductId
AND Criteria.TestCd = Measurement.TestCd
WHERE
Measurement.ProductId = 'A'
AND Criteria.SpecCd = 'S'
AND Measurement.TestDt =
(
SELECT
MAX(TestDt)
FROM
ProductMeasurement
WHERE
ProductId = Measurement.ProductId
)
You could remove the filters for ProductId and SpecCd and roll that into a view - users could later specify for the Products and specifications they want later.
If you want result as of a given date, the query is easily modified to this or incorporated into a TVF:
SELECT
Measurement.ProductId
,Measurement.TestCd
,Measurement.TestDt
,Criteria.SpecCd
,Measurement.Value
,CASE
WHEN Measurement.Value BETWEEN Criteria.LowerValue AND Criteria.UpperValue THEN 'Pass'
ELSE 'Fail'
END AS Result
FROM
ProductMeasurement Measurement
INNER JOIN
ProductTestCriteria Criteria
ON Critera.ProductId = Measurement.ProductId
AND Criteria.TestCd = Measurement.TestCd
WHERE
Measurement.ProductId = 'A'
AND Criteria.SpecCd = 'S'
AND Measurement.TestDt =
(
SELECT
MAX(TestDt)
FROM
ProductMeasurement
WHERE
ProductId = Measurement.ProductId
AND TestDt <= <Your Date>
)

Is there a way to sum an entire quantity in SQL with unique values

I am trying to get a total summation of both the ItemDetail.Quantity column and ItemDetail.NetPrice column. For sake of example, let's say the quantity that is listed is for each individual item is 5, 2, and 4 respectively. I am wondering if there is a way to display quantity as 11 for one single ItemGroup.ItemGroupName
The query I am using is listed below
select Location.LocationName, ItemDetail.DOB, SUM (ItemDetail.Quantity) as "Quantity",
ItemGroup.ItemGroupName, SUM (ItemDetail.NetPrice)
from ItemDetail
Join ItemGroupMember
on ItemDetail.ItemID = ItemGroupMember.ItemID
Join ItemGroup
on ItemGroupMember.ItemGroupID = ItemGroup.ItemGroupID
Join Location
on ItemDetail.LocationID = Location.LocationID
Inner Join Item
on ItemDetail.ItemID = Item.ItemID
where ItemGroup.ItemGroupID = '78' and DOB = '11/20/2019'
GROUP BY Location.LocationName, ItemDetail.DOB, Item.ItemName,
ItemDetail.NetPrice, ItemGroup.ItemGroupName
If you are using SQL Server 2012 , you can use the summation on partition to display the
details and aggregates in the same query.
SUM(SalesYTD) OVER (ORDER BY DATEPART(yy,ModifiedDate)),1)
Link :
https://learn.microsoft.com/en-us/sql/t-sql/functions/sum-transact-sql?view=sql-server-ver15
We can't be certain without seeing sample data. But I suspect you need to remove some fields from you GROUP BY clause -- probably Item.ItemName and ItemDetail.NetPrice.
Generally, you won't GROUP BY a column that you are applying an aggregate function to in the SELECT -- as in SUM(ItemDetail.NetPrice). And it is not very common, in my experience, to GROUP BY columns that aren't included in the SELECT list - as you are doing with Item.ItemName.
I think you need to go back to basics and read about what GROUP BY does.
First of all welcome to the overflow...
Second: The answer is going to be "It depends"
Any time you aggregate data you will need to Group by the other fields in the query, and you have that in the query. The gotcha is what happens when data is spread across multiple locations.
My suggestion is to rethink your problem and see if you really need these other fields in the query. This will depend on what the person using the data really wants to know.
Do they need to know how many of item X there are, or do they really need to know that item X is spread out over three sites?
You might find you are better off with two smaller queries.

Summing up values from one column into one row on a different table when joining

I've only had a (frustrating) couple days experience with SQL Server, and I need some help, since I cant find anything related to my question when searching.
For background info, I'm working in an accountancy, and right now I'm trying to create a table for balance statements to use in crystal reports. Each invoice has multiple items, but for the statement I need to sum them all up with the invoice reference being the information that links the group of data that needs to be summarised.
So, what I need is to pull information from one table (dbo.SalesInvItems), this information including the date (InvDate), the due date (InvDueDate), and the customer name (CustomerName). This information stays the same with the Invoice Reference (InvRef), and it's what I want to use to link the two tables.
For example, Invoice Reference: 1478 will always have the date 14/05/18, the due date: 14/06/18 and the customer name: Pen Sellers Ltd.
The same Invoice Reference is used by multiple rows, but the only thing that changes (that I need) is the Invoice Item Total (InvItemTotal).
For example, the one reference will always be addressed to Pen Sellers, but one item has the Total as £13 and another item using the same reference is £20.
The Invoice Item Total is what I need to sum up. I want to add all the Invoice Item Total's together that have the same Invoice Reference, while joining the tables.
Sales Invoices
So when I've inserted the references into the table (sorry they're not the same in both pictures, I was having problems making examples and I made a mistake), I want to grab the information from the Invoice table to fill it in, going from this...
Pre Solution
To this...
Desired Result
The desired location is a table called dbo.Statement.
1.Is this even possible to do?
2.How would I go about doing this?
3.Is there a method I could use that would make sure that every time I insert an Invoice Reference into the Statement table, it would automatically pull out the data needed from the Invoice Table?
If any additional information is needed, just say and I'll do my best to provide it, I have never asked a question on here before and I'm new to SQL Server and coding in general.
Im using SQL Server Management Tool 2017
Thank You
Select item.InvRef
, item.CustomerName
, item.InvDate
, item.InvDueDate
, Sum(item.InvItemTotal) InvAmt
, sum(IsNull(payments.Amount,0)) PayAmount
, Sum(item.InvItemTotal) InvAmt - sum(IsNull(payments.Amount,0)) as Balance
from SalesInvItems item
left join payments -- you didn't define this
on item.InvRef = payments.InvRef
group by item.InvRef
, item.CustomerName
, item.InvDate
, item.InvDueDate
Select item.InvRef
, item.CustomerName
, item.InvDate
, item.InvDueDate
, Sum(item.InvItemTotal) InvAmt
from SalesInvItems item
left join Statement
on item.InvRef = Statement.Reference
group by item.InvRef
, item.CustomerName
, item.InvDate
, item.InvDueDate

Crystal report - Group Towns by Countries

I have two tables
With this query i got the results
select countries.id, countries.name, Towns.id,Towns.TownName
from
Countries
left outer join Towns on countries.id = towns.countryID
Now i want to group results by country to get something like this on my CrystalReport. Is it even possible to make it ?
In the example you have provided, doing a GROUP BY in Sql Server would not be desirable. A Sql GROUP BY is generally used to project single scalar values from a list in each group, e.g.
SELECT Countries.Name, Count(Towns.Id) AS NumberOfTowns, Sum(Towns.Population) AS TotalPop
FROM Countries
LEFT OUTER JOIN Towns
ON Countries.Id = Towns.CountryID
GROUP BY Countries.Name;
Would give results like
Name NumberOfTowns TotalPop
Bosnia 2 123456
England 2 98765
by applying the Aggregates COUNT and SUM to all rows (Towns) in each country.
This isn't going to be useful for your report, as you need to show a list of all towns per country.
What you want instead is to use your current query as-is, and then to apply a Crystal Group Header on Countries.Name. Then, in Crystal, remove the Countries.Name field from the Details section (since you don't want the country repeated). You'll possibly also want some ordering done in the groups and data - again, I would suggest you do this in Crystal (although an ORDER BY Countries.Name, Towns.TownName would also work).
You'll then have a report which resembles your requirement.

Resources