How to write an optimized DAX Measure to aggregate a value by two group by attributesDAX / PowerPivot query functions to spread aggregated values over time periodAggregation on different level of dimension hierarchyoptimizing dax distinct aggregateHow do I get my DAX measure to calculate grouped values?How to construct SSAS Tabular Model DAX expression for all measures in a query contextHow to optimize MDX that should conditionally decide between two Measures based on the half Year choosen (involving SCOPE, Descendants Statements)Optimizing Summarize in DAXDAX Measure to Sum the value of the columnDAX grouping by a measure resultWeeknum function is not working correctly

How does the Earth's center produce heat?

Possibility of faking someone's public key

I want to ask company flying me out for office tour if I can bring my fiance

What could be my risk mitigation strategies if my client wants to contract UAT?

Are there guidelines for finding good names for LaTeX 2e packages and control sequences defined in these packages?

Local variables in DynamicModule affected by outside evaluation

Does water in vacuum form a solid shell or freeze solid?

Fill area of x^2+y^2>1 and x^2+y^2>4 using patterns and tikzpicture

Complications of displaced core material?

Cisco 3750X Power Cable

Are there any German nonsense poems (Jabberwocky)?

Who wrote “A writer only begins a book. A reader finishes it.”?

Can I render satellite deployment impossible, or at least impractical, by exploiting the Kessler syndrome?

Visual Block Mode edit with sequential number

Why did Drogon spare this character?

Are cells guaranteed to get at least one mitochondrion when they divide?

Ribbon Cable Cross Talk - Is there a fix after the fact?

How would a developer who mostly fixed bugs for years at a company call out their contributions in their CV?

What did the 'turbo' button actually do?

Time complexity of an algorithm: Is it important to state the base of the logarithm?

What is Orcus doing with Mind Flayers in the art on the last page of Volo's Guide to Monsters?

How can I minimize the damage of an unstable nuclear reactor to the surrounding area?

Using too much dialogue?

Split into three!



How to write an optimized DAX Measure to aggregate a value by two group by attributes


DAX / PowerPivot query functions to spread aggregated values over time periodAggregation on different level of dimension hierarchyoptimizing dax distinct aggregateHow do I get my DAX measure to calculate grouped values?How to construct SSAS Tabular Model DAX expression for all measures in a query contextHow to optimize MDX that should conditionally decide between two Measures based on the half Year choosen (involving SCOPE, Descendants Statements)Optimizing Summarize in DAXDAX Measure to Sum the value of the columnDAX grouping by a measure resultWeeknum function is not working correctly






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








1















What if we need to aggregate (Sum) of a value group by two attributes in DAX. I wrote the following measure with Summarize function but it is very slow.



Reorder :=
SUMX (
SUMMARIZE (
TableA,
TableA[ProdID],
TableA[CustID],
"ReordersCount",
VAR VarInvoiceCount =
SUM ( TableA[InvoiceCount] )
RETURN
IF ( VarInvoiceCount > 0, VarInvoiceCount - 1, 0 )
),
[ReordersCount]
)


I also looked for SummarizeColumns but its not working in the report when I am applying other attributes slicers. May be I am missing something?
Looking for optimized solution. Many thanks in advance.










share|improve this question
























  • You could also load that data into a DAX calculated table, with many:1 relationships to each of Product and Customer, and storing the ReordersCount for each (ProdID,CustID) pair. The aggregate table would be reloaded on refresh, and very fast to query. Of course if you did that, only filters on Customer or Product would be reflected in the measure.

    – David Browne - Microsoft
    Mar 24 at 0:30


















1















What if we need to aggregate (Sum) of a value group by two attributes in DAX. I wrote the following measure with Summarize function but it is very slow.



Reorder :=
SUMX (
SUMMARIZE (
TableA,
TableA[ProdID],
TableA[CustID],
"ReordersCount",
VAR VarInvoiceCount =
SUM ( TableA[InvoiceCount] )
RETURN
IF ( VarInvoiceCount > 0, VarInvoiceCount - 1, 0 )
),
[ReordersCount]
)


I also looked for SummarizeColumns but its not working in the report when I am applying other attributes slicers. May be I am missing something?
Looking for optimized solution. Many thanks in advance.










share|improve this question
























  • You could also load that data into a DAX calculated table, with many:1 relationships to each of Product and Customer, and storing the ReordersCount for each (ProdID,CustID) pair. The aggregate table would be reloaded on refresh, and very fast to query. Of course if you did that, only filters on Customer or Product would be reflected in the measure.

    – David Browne - Microsoft
    Mar 24 at 0:30














1












1








1








What if we need to aggregate (Sum) of a value group by two attributes in DAX. I wrote the following measure with Summarize function but it is very slow.



Reorder :=
SUMX (
SUMMARIZE (
TableA,
TableA[ProdID],
TableA[CustID],
"ReordersCount",
VAR VarInvoiceCount =
SUM ( TableA[InvoiceCount] )
RETURN
IF ( VarInvoiceCount > 0, VarInvoiceCount - 1, 0 )
),
[ReordersCount]
)


I also looked for SummarizeColumns but its not working in the report when I am applying other attributes slicers. May be I am missing something?
Looking for optimized solution. Many thanks in advance.










share|improve this question
















What if we need to aggregate (Sum) of a value group by two attributes in DAX. I wrote the following measure with Summarize function but it is very slow.



Reorder :=
SUMX (
SUMMARIZE (
TableA,
TableA[ProdID],
TableA[CustID],
"ReordersCount",
VAR VarInvoiceCount =
SUM ( TableA[InvoiceCount] )
RETURN
IF ( VarInvoiceCount > 0, VarInvoiceCount - 1, 0 )
),
[ReordersCount]
)


I also looked for SummarizeColumns but its not working in the report when I am applying other attributes slicers. May be I am missing something?
Looking for optimized solution. Many thanks in advance.







performance ssas powerbi dax summarize






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 23 at 21:46









RADO

3,9332923




3,9332923










asked Mar 23 at 21:45









SKhanSKhan

82




82












  • You could also load that data into a DAX calculated table, with many:1 relationships to each of Product and Customer, and storing the ReordersCount for each (ProdID,CustID) pair. The aggregate table would be reloaded on refresh, and very fast to query. Of course if you did that, only filters on Customer or Product would be reflected in the measure.

    – David Browne - Microsoft
    Mar 24 at 0:30


















  • You could also load that data into a DAX calculated table, with many:1 relationships to each of Product and Customer, and storing the ReordersCount for each (ProdID,CustID) pair. The aggregate table would be reloaded on refresh, and very fast to query. Of course if you did that, only filters on Customer or Product would be reflected in the measure.

    – David Browne - Microsoft
    Mar 24 at 0:30

















You could also load that data into a DAX calculated table, with many:1 relationships to each of Product and Customer, and storing the ReordersCount for each (ProdID,CustID) pair. The aggregate table would be reloaded on refresh, and very fast to query. Of course if you did that, only filters on Customer or Product would be reflected in the measure.

– David Browne - Microsoft
Mar 24 at 0:30






You could also load that data into a DAX calculated table, with many:1 relationships to each of Product and Customer, and storing the ReordersCount for each (ProdID,CustID) pair. The aggregate table would be reloaded on refresh, and very fast to query. Of course if you did that, only filters on Customer or Product would be reflected in the measure.

– David Browne - Microsoft
Mar 24 at 0:30













1 Answer
1






active

oldest

votes


















1














Consider the following approach:



First, create a measure for total number of invoices:



Total Invoice Count = SUM(TableA[InvoiceCount])


Second, create a measure to count a number of first-time invoices, which is simply a number of unique product-customer combinations in your table:



First Invoice Count =
COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )


Finally, the desired result is simply the difference of these two measures:



Reorder Count = [Total Invoice Count] - [First Invoice Count]


The formula will respond properly to all slicers and filters, and should be very fast because there are no nested iteration loops such as SUMX(SUMMARIZE()), no context transitions and no call-backs inside the loops caused by using IF statements (that's a bit of an advanced topic).



Of course, you can put everything in one measure using variables:



Reorder Count = 
VAR Total_Invoice_Count = SUM(TableA[InvoiceCount])
VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
VAR Reorder_Count = Total_Invoice_Count - First_Invoice_Count
RETURN Reorder_Count


although personally I prefer to break measures down because individual measures are easier to understand and debug, and they might have their own use.



The above approach is very efficient, but it assumes that TableA contains only valid orders. If it also has cancellations, returns, etc., that might have zero or negative Invoice counts, then you will have to use a less efficient approach, such as:



Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
VAR Reorder_Count = CALCULATE ( SUM ( TableA[Invoice] ) ) - 1
RETURN
IF ( Reorder_Count > 0, Reorder_Count, 0 )
)


or:



Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
MAX(CALCULATE ( SUM ( TableA[Invoice] ) ) - 1, 0) )


Nevertheless, they should be still faster than your original formula.






share|improve this answer

























  • Thank you so much @RADO your first suggestion is working so far perfectly and execution time has been reduced drastically. I only improvised it a little bit to add a filter while calculating First_Invoice_Count since my table do have returned orders (InvoiceCount = 0). The one line I updated (FILTER) as follows: VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( FILTER ( Transactions, Transactions[InvoiceCount] > 0 ), Transactions[CustomerKey], Transactions[ProductKey] ) )

    – SKhan
    Mar 25 at 3:09











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55318691%2fhow-to-write-an-optimized-dax-measure-to-aggregate-a-value-by-two-group-by-attri%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Consider the following approach:



First, create a measure for total number of invoices:



Total Invoice Count = SUM(TableA[InvoiceCount])


Second, create a measure to count a number of first-time invoices, which is simply a number of unique product-customer combinations in your table:



First Invoice Count =
COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )


Finally, the desired result is simply the difference of these two measures:



Reorder Count = [Total Invoice Count] - [First Invoice Count]


The formula will respond properly to all slicers and filters, and should be very fast because there are no nested iteration loops such as SUMX(SUMMARIZE()), no context transitions and no call-backs inside the loops caused by using IF statements (that's a bit of an advanced topic).



Of course, you can put everything in one measure using variables:



Reorder Count = 
VAR Total_Invoice_Count = SUM(TableA[InvoiceCount])
VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
VAR Reorder_Count = Total_Invoice_Count - First_Invoice_Count
RETURN Reorder_Count


although personally I prefer to break measures down because individual measures are easier to understand and debug, and they might have their own use.



The above approach is very efficient, but it assumes that TableA contains only valid orders. If it also has cancellations, returns, etc., that might have zero or negative Invoice counts, then you will have to use a less efficient approach, such as:



Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
VAR Reorder_Count = CALCULATE ( SUM ( TableA[Invoice] ) ) - 1
RETURN
IF ( Reorder_Count > 0, Reorder_Count, 0 )
)


or:



Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
MAX(CALCULATE ( SUM ( TableA[Invoice] ) ) - 1, 0) )


Nevertheless, they should be still faster than your original formula.






share|improve this answer

























  • Thank you so much @RADO your first suggestion is working so far perfectly and execution time has been reduced drastically. I only improvised it a little bit to add a filter while calculating First_Invoice_Count since my table do have returned orders (InvoiceCount = 0). The one line I updated (FILTER) as follows: VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( FILTER ( Transactions, Transactions[InvoiceCount] > 0 ), Transactions[CustomerKey], Transactions[ProductKey] ) )

    – SKhan
    Mar 25 at 3:09















1














Consider the following approach:



First, create a measure for total number of invoices:



Total Invoice Count = SUM(TableA[InvoiceCount])


Second, create a measure to count a number of first-time invoices, which is simply a number of unique product-customer combinations in your table:



First Invoice Count =
COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )


Finally, the desired result is simply the difference of these two measures:



Reorder Count = [Total Invoice Count] - [First Invoice Count]


The formula will respond properly to all slicers and filters, and should be very fast because there are no nested iteration loops such as SUMX(SUMMARIZE()), no context transitions and no call-backs inside the loops caused by using IF statements (that's a bit of an advanced topic).



Of course, you can put everything in one measure using variables:



Reorder Count = 
VAR Total_Invoice_Count = SUM(TableA[InvoiceCount])
VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
VAR Reorder_Count = Total_Invoice_Count - First_Invoice_Count
RETURN Reorder_Count


although personally I prefer to break measures down because individual measures are easier to understand and debug, and they might have their own use.



The above approach is very efficient, but it assumes that TableA contains only valid orders. If it also has cancellations, returns, etc., that might have zero or negative Invoice counts, then you will have to use a less efficient approach, such as:



Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
VAR Reorder_Count = CALCULATE ( SUM ( TableA[Invoice] ) ) - 1
RETURN
IF ( Reorder_Count > 0, Reorder_Count, 0 )
)


or:



Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
MAX(CALCULATE ( SUM ( TableA[Invoice] ) ) - 1, 0) )


Nevertheless, they should be still faster than your original formula.






share|improve this answer

























  • Thank you so much @RADO your first suggestion is working so far perfectly and execution time has been reduced drastically. I only improvised it a little bit to add a filter while calculating First_Invoice_Count since my table do have returned orders (InvoiceCount = 0). The one line I updated (FILTER) as follows: VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( FILTER ( Transactions, Transactions[InvoiceCount] > 0 ), Transactions[CustomerKey], Transactions[ProductKey] ) )

    – SKhan
    Mar 25 at 3:09













1












1








1







Consider the following approach:



First, create a measure for total number of invoices:



Total Invoice Count = SUM(TableA[InvoiceCount])


Second, create a measure to count a number of first-time invoices, which is simply a number of unique product-customer combinations in your table:



First Invoice Count =
COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )


Finally, the desired result is simply the difference of these two measures:



Reorder Count = [Total Invoice Count] - [First Invoice Count]


The formula will respond properly to all slicers and filters, and should be very fast because there are no nested iteration loops such as SUMX(SUMMARIZE()), no context transitions and no call-backs inside the loops caused by using IF statements (that's a bit of an advanced topic).



Of course, you can put everything in one measure using variables:



Reorder Count = 
VAR Total_Invoice_Count = SUM(TableA[InvoiceCount])
VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
VAR Reorder_Count = Total_Invoice_Count - First_Invoice_Count
RETURN Reorder_Count


although personally I prefer to break measures down because individual measures are easier to understand and debug, and they might have their own use.



The above approach is very efficient, but it assumes that TableA contains only valid orders. If it also has cancellations, returns, etc., that might have zero or negative Invoice counts, then you will have to use a less efficient approach, such as:



Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
VAR Reorder_Count = CALCULATE ( SUM ( TableA[Invoice] ) ) - 1
RETURN
IF ( Reorder_Count > 0, Reorder_Count, 0 )
)


or:



Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
MAX(CALCULATE ( SUM ( TableA[Invoice] ) ) - 1, 0) )


Nevertheless, they should be still faster than your original formula.






share|improve this answer















Consider the following approach:



First, create a measure for total number of invoices:



Total Invoice Count = SUM(TableA[InvoiceCount])


Second, create a measure to count a number of first-time invoices, which is simply a number of unique product-customer combinations in your table:



First Invoice Count =
COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )


Finally, the desired result is simply the difference of these two measures:



Reorder Count = [Total Invoice Count] - [First Invoice Count]


The formula will respond properly to all slicers and filters, and should be very fast because there are no nested iteration loops such as SUMX(SUMMARIZE()), no context transitions and no call-backs inside the loops caused by using IF statements (that's a bit of an advanced topic).



Of course, you can put everything in one measure using variables:



Reorder Count = 
VAR Total_Invoice_Count = SUM(TableA[InvoiceCount])
VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
VAR Reorder_Count = Total_Invoice_Count - First_Invoice_Count
RETURN Reorder_Count


although personally I prefer to break measures down because individual measures are easier to understand and debug, and they might have their own use.



The above approach is very efficient, but it assumes that TableA contains only valid orders. If it also has cancellations, returns, etc., that might have zero or negative Invoice counts, then you will have to use a less efficient approach, such as:



Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
VAR Reorder_Count = CALCULATE ( SUM ( TableA[Invoice] ) ) - 1
RETURN
IF ( Reorder_Count > 0, Reorder_Count, 0 )
)


or:



Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
MAX(CALCULATE ( SUM ( TableA[Invoice] ) ) - 1, 0) )


Nevertheless, they should be still faster than your original formula.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 24 at 0:10

























answered Mar 23 at 22:29









RADORADO

3,9332923




3,9332923












  • Thank you so much @RADO your first suggestion is working so far perfectly and execution time has been reduced drastically. I only improvised it a little bit to add a filter while calculating First_Invoice_Count since my table do have returned orders (InvoiceCount = 0). The one line I updated (FILTER) as follows: VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( FILTER ( Transactions, Transactions[InvoiceCount] > 0 ), Transactions[CustomerKey], Transactions[ProductKey] ) )

    – SKhan
    Mar 25 at 3:09

















  • Thank you so much @RADO your first suggestion is working so far perfectly and execution time has been reduced drastically. I only improvised it a little bit to add a filter while calculating First_Invoice_Count since my table do have returned orders (InvoiceCount = 0). The one line I updated (FILTER) as follows: VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( FILTER ( Transactions, Transactions[InvoiceCount] > 0 ), Transactions[CustomerKey], Transactions[ProductKey] ) )

    – SKhan
    Mar 25 at 3:09
















Thank you so much @RADO your first suggestion is working so far perfectly and execution time has been reduced drastically. I only improvised it a little bit to add a filter while calculating First_Invoice_Count since my table do have returned orders (InvoiceCount = 0). The one line I updated (FILTER) as follows: VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( FILTER ( Transactions, Transactions[InvoiceCount] > 0 ), Transactions[CustomerKey], Transactions[ProductKey] ) )

– SKhan
Mar 25 at 3:09





Thank you so much @RADO your first suggestion is working so far perfectly and execution time has been reduced drastically. I only improvised it a little bit to add a filter while calculating First_Invoice_Count since my table do have returned orders (InvoiceCount = 0). The one line I updated (FILTER) as follows: VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( FILTER ( Transactions, Transactions[InvoiceCount] > 0 ), Transactions[CustomerKey], Transactions[ProductKey] ) )

– SKhan
Mar 25 at 3:09



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55318691%2fhow-to-write-an-optimized-dax-measure-to-aggregate-a-value-by-two-group-by-attri%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

은진 송씨 목차 역사 본관 분파 인물 조선 왕실과의 인척 관계 집성촌 항렬자 인구 같이 보기 각주 둘러보기 메뉴은진 송씨세종실록 149권, 지리지 충청도 공주목 은진현