Complex sorting lines in SAP B1 - sapb1

This is a question already posted on another forum but it has not yet recieved any answers:
We have a requirement to enter all our purchase orders to a particular client in a special way so they can eneter it directly into their system from our order. Doing it manually takes us a lot of time having to simply add rows as the order is created. If I could somehow overcome this either via a button or a user process it would be great. See below the way we need to sort:
By Length - this needs to be numerical sort i.e. 12 needs to be after 9 not between 1 and 2
Then by Colour - retaining the length sort for each colour we then need to sort by colour - doesn't need to be alphabetical, just grouped in colour type
Then by item code - there is only 2 item codes concerned. Same as above, retaning the previous 2 sortings we need to then sort by these item codes.
So at the top you wil have all the "Item Code A" items in Pink from shortest to longest. Then you will have all the "Item Code A" items in Green from shortest to longest. Then you will have all "Item code B" items in Pink from shortest to longest. Finally you will have all the "Item Code B" items in Green from shortest to longest.

You can use a query
just change the values to fit your DB
SELECT T1.[ItemCode], T1.[Quantity], T2.[SLength1], T2.[SHeight1], T2.[Width]
FROM OPOR T0
INNER JOIN POR1 T1 ON T0.[DocEntry] = T1.[DocEntry]
INNER JOIN OITM T2 ON T1.[ItemCode] = T2.[ItemCode]
WHERE T0.[CardCode] = [%0]
ORDER BY T2.[ItemCode], T2.[SHeight1], T2.[SWidth1], T2.[SLength1]

Related

MS-Access: Finding records with multiple matching criteria

I'm learning on the go and really appreciate any help you can give me.
I need to calculate a record's first appearance in my 'issue log' table.
Raw data is added to the table once per week. If an issue is resolved by the next run, it will be omitted, but if the issue is still there a new record will be appended into the table.
I need to populate a new column with when issue first appeared. The challenge is that if a record is omitted from the previous run, the counter 'resets'.
table example - records are added once per week (can take place on different days), record is a repeat if there is a match between certain fields (in this example "country" and "material") and the column that needs to be populated is the "first appearance" column.
Any help is appreciated! :)
Edit - just to clarify, I'm not looking for a code, just an idea on how to tackle this. I was thinking of adding the date for the previous report as an additional column, with a VB counting each consecutive appearance, but it seems like there might be an easier solution. Any ideas are welcome, Thanks!
Assuming that your screenshot is a representation of an Access table (Table1) then you need to SELECT the MINinimum date for each GROUP of Country & Material fields FROM Table1.
Try:
SELECT MIN(dDate) AS First_Appearance,
Country,
Material
FROM Table1
GROUP BY Country,
Material
ORDER BY MIN(dDate)
Edit:
Based on your example data you should only be showing Romania, Ukraine and Israel with material C as these are the only records that appear in the latest week (11/09/2016).
Israel only appears once, so that date is its first appearance.
Romania appears on the 11th and 28th. As it didn't appear on the 4th then the 11th is it's first appearance.
Ukraine appears on the 11th and 4th, so its first appearance is the 4th.
SELECT T1.dDate
, T1.Country
, T1.Material
, MIN(T2.dDate) AS First_Appearance
FROM Table1 T1 INNER JOIN Table1 T2 ON
T1.Country = T2.Country AND
T1.Material = T2.Material AND
(T2.dDate + 7 = T1.dDate or T2.dDate = T1.dDate)
WHERE T1.dDate = (SELECT MAX(dDate) FROM Table1)
GROUP BY T1.Country, T1.Material, T1.dDate
ORDER BY T1.Country, T1.Material
If you were to look at the previous week (change your WHERE clause to WHERE T1.dDate = #09/04/2016#) you'd get:
Dubai B with a first appearance of 28th.
Romania B with a first appearance of 4th.
Spain A with a first appearance of 28th.
Ukraine C with a first appearance of 4th.

Sql Full Text keyword search - contains or not contains

Hi i was asked to upgrade our website s keyword search section. It needs to be like in the picture.
The user can select from two different options from select box and it refers to my full text indexed column. Then he/she enter a pharese or word and says add. It goes to "contains box" and it means that search result needs to contains that word. If the user drags it to the other box search results shouldnt contains that word/s.
I did it some way. But im concerned about the performance. These searches occurs in every 15 seconds in average and the table has ~30 million records.
This is what i did:
INNER JOIN CONTAINSTABLE (FullTextDB,column1,'"software developer*"') ka on a.refnumber = ka.[key]
left JOIN CONTAINSTABLE (FullTextDB,column1,'"mvc*" ') ri on a.refnumber = ri.[key]
INNER JOIN CONTAINSTABLE (FullTextDB,column2,'"php*" ') yer on a.refnumber = yer.[key]
WHERE ri.[key] is null
It brings correct results but how can i improve this. I used left join to exclude. Any ideas?
Thank you.
Grouping your search keywords will provide improved performance
example
"(A OR B) AND NOT (C)"

How to solve this with SQL?

I have a query which I have to modify in order to meet some new specifications:
The big picture of the query is below:
I have a few INNER JOINS which make up the result set of INNER JOINS, then that result set is LEFT JOINED with A1 first, then secondly with SCH. This is the current state of the query.
Now, what I have to do is add anoter result set, A2 which for the common part of A1 and A2 (the yellow part), to display the records with the current conditions in the GROUP BY.
My problem is that I still have to display SOME of the records in the blue area (which are common with the initial set, but not common with the new set which I am adding).
I do not know how can I refference those records that are in the blue arrea and FILTER them out (choose those which meet only one condition), without filtering records from A2. I do not know what kind of JOIN to use for A2 (I think I should use INNER JOIN, but I am not sure, that is why there is a ? mark on my diagram).
FILTER blue -> ALL yellow
I don't know if you are trying to do all in one single query or even if is it possible. Otherwise I think you should use a query like
SELECT your,fields
FROM (table/subquery)
WHERE keyfield
IS NOT IN (table/subquery)
to select the blue part of data
According to your diagram you want something like this:
SELECT * FROM InnerJoins -- whatever the previous inner joins are
INNER JOIN A1 ON A1.Key = InnerJoins.Key
INNER JOIN SCH ON SCH.Key = InnerJoins.Key
-- Do all inner joins up to here
-- the statement up to here includes the blue and yellow areas only
LEFT OUTER JOIN A2 ON A2.Key = InnerJoins.Key
-- this still includes the blue and yellow areas combined
WHERE A2.Key IS NULL
-- now we are excluding the yellow area as we are asking for the bits where we have no match in A2.

Is there away in SQL Server to sort by the number of matched words in a contains function on a full text index

I have a table in a database that has a description of an item. I want to be able to have the user type a search term and return the rows that had at least one match, sorted by the number of matches they had, descending.
I don't know if this is possible, I haven't been able to find an answer googling so I'm coming here.
Basically if the user enters "truck blue with gold two tone", this will be generated:
SELECT * FROM MyItemsTable
WHERE contains(Description, 'truck or blue or with or gold or two or tone')
and have that return sorted by the number of words that matched.
Any advice would be greatly appreciated. This table will become very large in time so efficiency is also in the back of my mind as well.
This seems to have worked very well, thanks very much to Gordon Linoff.
SELECT * FROM MyItemsTable m
INNER JOIN
CONTAINSTABLE(MyItemsTable, Description, 'truck or blue or with or gold or two or tone') AS l ON m.MyItemsTable=l.[KEY]
Reference
In case you have a record like "truck blue with gold two tone". You can use below query.
SELECT * FROM
MyItemsTable as t
JOIN CONTAINSTABLE(MyItemsTable , Description,'"truck"') fulltextSearch
ON
t.[Id] = fulltextSearch.[KEY]
This will also bring this record.

looping through a numeric range for secondary record ID

So, I figure I could probably come up with some wacky solution, but i figure i might as well ask up front.
each user can have many orders.
each desk can have many orders.
each order has maximum 3 items in it.
trying to set things up so a user can create an order and the order auto generates a reference number and each item has a reference letter. reference number is 0-99 and loops back around to 0 once it hits 99, so orders throughout the day are easy to reference for the desks.
So, user places an order for desk #2 of 3 items:
78A: red stapler
78B: pencils
78C: a kangaroo foot
not sure if this would be done in the program logic or done at the SQL level somehow.
was thinking something like neworder = order.last + 1 and somehow tying that into a range on order create. pretty fuzzy on specifics.
Without knowing the answer to my comment above, I will assume you want to have the full audit stored, rather than wiping historic records; as such the 78A 78B 78C type orders are just a display format.
If you have a single Order table (containing your OrderId, UserId, DeskId, times and any other top-level stuff) and an OrderItem table (containing your OrderItemId, OrderId, LineItemId -- showing 1,2 or 3 for your first and optional second and third line items in the order, and ProductId) and a Product table (ProductId, Name, Description)
then this is quite simple (thankfully) using the modulo operator, which gives the remainder of a division, allowing you in this case to count in groups of 3 and 100 (or any other number you wish).
Just do something like the following:
(you will want to join the items into a single column, I have just kept them distinct so that you can see how they work)
Obviously join/query/filter on user, desk and product tables as appropriate
select
o.OrderId,
o.UserId,
o.DeskId
o.OrderId%100 + 1 as OrderNumber,
case when LineItem%3 = 1 then 'A'
when LineItem%3 = 2 then 'B'
when LineItem%3 = 0 then 'C'
end as ItemLetter,
oi.ProductId
from tb_Order o inner join tb_OrderItem oi on o.OrderId=oi.OrderId
Alternatively, you can add the itemLetter (A,B,C) and/or the OrderNumber (1-100) as computed (and persisted) columns on the tables themselves, so that they are calculated once when inserted, rather than recalculating/formatting when they are selected.
This sort-of breaks some best practice that you store the raw data in the DB and you format on retrieval; but if you are not going to update the data and you are going to select the data for more than you are going to write the data; then I would break this rule and calculate your formatting at insert time